/*
 * DMG cracker patch for JtR. Hacked together during August of 2012
 * by Dhiru Kholia <dhiru.kholia at gmail.com>
 *
 * This software is
 * Copyright (c) 2012, Dhiru Kholia <dhiru.kholia at gmail.com>
 * Copyright (c) 2015, magnum
 * and is based on "dmg.c" from
 *
 * hashkill - a hash cracking tool
 * Copyright (C) 2010 Milen Rangelov <gat3way@gat3way.eu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * References:
 *
 * http://lingrok.org/xref/syslinux/utils/isohybrid.c#apple_part_header
 * http://www.dubeyko.com/development/FileSystems/HFSPLUS/hexdumps/hfsplus_volume_header.html
 */

/*
 *  Debug levels:
 *   1 show what "test" hits
 *   2 dump printables from the decrypted blocks
 *   3 dump hex from the decrypted blocks
 *   4 dump decrypted blocks to files (will overwrite with no mercy):
 *       dmg.debug.main   main block
 *       dmg.debug        alternate block (if present, this is the start block)
 */
//#define DMG_DEBUG		2

#if FMT_EXTERNS_H
extern struct fmt_main fmt_dmg;
#elif FMT_REGISTERS_H
john_register_one(&fmt_dmg);
#else

#if AC_BUILT
#include "autoconfig.h"
#endif

#include <string.h>
#include <errno.h>
#if !AC_BUILT || HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <stdlib.h>
#include "stdint.h"
#include <sys/types.h>
#include <openssl/des.h>
#include "aes.h"
#include "hmac_sha.h"
#ifdef _OPENMP
#include <omp.h>
#ifndef OMP_SCALE
#define OMP_SCALE               64
#endif
#endif

#ifdef DMG_DEBUG
#define NEED_OS_FLOCK
#include "os.h"
#endif
#include "arch.h"
#include "jumbo.h"
#include "params.h"
#include "johnswap.h"
#include "common.h"
#include "formats.h"
#include "pbkdf2_hmac_sha1.h"
#ifdef DMG_DEBUG
#include <sys/file.h>
#if (!AC_BUILT || HAVE_UNISTD_H) && !_MSC_VER
#include <unistd.h>
#endif
extern volatile int bench_running;
#endif
#include "loader.h"
#include "memdbg.h"

#define FORMAT_LABEL        "dmg"
#define FORMAT_NAME         "Apple DMG"
#define FORMAT_TAG           "$dmg$"
#define FORMAT_TAG_LEN       (sizeof(FORMAT_TAG)-1)
#ifdef SIMD_COEF_32
#define ALGORITHM_NAME      "PBKDF2-SHA1 " SHA1_ALGORITHM_NAME " 3DES/AES"
#else
#define ALGORITHM_NAME      "PBKDF2-SHA1 3DES/AES 32/" ARCH_BITS_STR
#endif
#define BENCHMARK_COMMENT   ""
#define BENCHMARK_LENGTH    -1001
#define BINARY_SIZE         0
#define PLAINTEXT_LENGTH	125
#define SALT_SIZE           sizeof(struct custom_salt)
#define BINARY_ALIGN		1
#define SALT_ALIGN			sizeof(int)
#ifdef SIMD_COEF_32
#define MIN_KEYS_PER_CRYPT  SSE_GROUP_SZ_SHA1
#define MAX_KEYS_PER_CRYPT  SSE_GROUP_SZ_SHA1
#else
#define MIN_KEYS_PER_CRYPT  1
#define MAX_KEYS_PER_CRYPT  1
#endif

#undef HTONL
#define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
		((((unsigned long)(n) & 0xFF00)) << 8) | \
		((((unsigned long)(n) & 0xFF0000)) >> 8) | \
		((((unsigned long)(n) & 0xFF000000)) >> 24))

#if defined (_OPENMP)
static int omp_t = 1;
#endif
static char (*saved_key)[PLAINTEXT_LENGTH + 1];
static int *cracked, cracked_count;

static struct custom_salt {
	unsigned int saltlen;
	unsigned char salt[20];
	unsigned int ivlen;
	unsigned char iv[32];
	int headerver;
	unsigned char chunk[8192];
	uint32_t encrypted_keyblob_size;
	uint8_t encrypted_keyblob[128];
	unsigned int len_wrapped_aes_key;
	unsigned char wrapped_aes_key[296];
	unsigned int len_hmac_sha1_key;
	unsigned char wrapped_hmac_sha1_key[300];
	char scp; /* start chunk present */
	unsigned char zchunk[4096]; /* chunk #0 */
	int cno;
	int data_size;
	unsigned int iterations;
} *cur_salt;

static struct fmt_tests dmg_tests[] = {
	// testimage.AES-256.64k.header_v2.dmg
	{"$dmg$2*20*fd70ac1e078f01fce55a2e56145a2494446db32a*32*9110b1778f09b1a7000000000000000000000000000000000000000000000000*64*68a32866b0e67515f35dc67c4d6747a8561a9f4f6a6718a894b0a77a47c452471e04ecef9bf56f0d83d1201a509a374e00000000000000000000000000000000*14*8192*70ebe6f1d387e33e3d1093cca2e94c9a32e2c9ba47d461d737d49a7dc1b1f69407b7dbc16f7671689ea4a4641652b3f976b6f1c73c551a0a407d5a335caa169db4a6a25bbd27fbbc38fc71b29ee9b1eae349b0d8a21d57959ecca6bf74bc26ccaee69cfee4999b55374605491af6d0b9066c26995209cd1b71925bcb45a8ef5727a6c20338f08de4357d4cb42cb65ecdc2344a5d7387633c913258ba40699ea5f88804b5e562bf973096337b17b4fc1236d3c8a80b9b48aed63c5a0eae3ae924a883e948f374771bba46923658f225fd2795ce0e795269f589e0ffc81615585e1224cddde654d689a3260e69683c6198bdfcd87507c23cefe36d72f8878cb27bbe5dce868752a7cce067f5a3110f20ebd31ecd53840103e0b2d44385656398edc487bf6d1a5ec3a56af54f9d4254fd20988df41eb85e366f13da1270a3f42c6672ad5faf00fa21e9ba3691bde78ab2c267a142f275467d5b853a107dbf1d75839f0e87b3b4f1d2cec88cc02a26bc4a63aa6836b0c43c5dbb44a832050385a48d46968361ebb053c2416c02458b76c95e50970922556d40b100967340a32824e6b6e44c0c1e0da7ce989d9d5ad91560156"
	 "ed39666cbfbea71f28797a5a7a40e77665612e977ecb8b7fe71d500eafc29d9a0ec1d0ff1723fea7c405bc181ea93c0df42f5bf886eace3cfeee8b0dba52ba8cd2ae009e75d8845264d12dd632ca3236bc1b643437881b270183d2e2bd20808ae73d32bfe88347e33bef4921fcfac9646b74f116be1f04fc353d2222499d5247fa842d0d0f00fc9642ea7524adb65c18fff87b6efd060ec850d7de6f59869387b3d4cc8e38014d52d94ead07d16b8d94327fe5533941497c9be2dd6c04142ba57e29daaeef96d0f2d109522651d797715f4bc5f4cc3fb69fa92623b5ea3e08ff78dc59913993c877f4e2c8964dffd2c8cde6c6b6738da2883505486df5b633aaa8c66acbc2886107f3dd61b1df29f54a13ef27a7d2785c02153375240885e5c54297d88827403320799e05213761549eedc1c159c922087983410d2abadf9ef8ae460d018c278a9ea724f52b866e3d7ff2374496103b5137297100c970d195fca8c1286a8f9d3859ee12c84bdaa4b56ca91e307580b61dbe435ce4021007e4a2a8085976549cf1d195f439bb6e642567f91a0224e98796614d9ea6bfab8f6d13f91b7a80a54e538a1a785cd07b5d7ed2b7e45a0658b5722b5f8844f5139cff3b33ce244946757c020c54c8b5e43324023ed11001201213ffe4829e37135686a8bec1837b35fb234049570868dc5ba9c84cef6890d9ec400a794b1723eb209a60758ba9ae9abd23a7ea9f94fc6b73d29a560e24973c9160f195fbe82376c81dfeec1a7f912a8c22c067a26786a22f0b7db298"
	 "3631400f120010706c78acc36ddcc29c7055fe82105f770e2dadf131ab49af93539fb5186d32dbe4a4df6cb0fdf6840c0609c8769fe242cc60d87e04e6e3be1a7884a05d9fb96c3bc1bbc769d96bbcc0413492eefc5502e9c1ac7c3f237b9851dc453b5bfa899b7b68e5e3b92711e7c92945feb6f6e452d6216e154a952cc28a3740925554d9fd44acedc8a44b0c25bbb6aa637fe9560437c08b17992c74de38fe1fb8fd5f66c2933c2d573ddc914f68f42d6cb350f126a51f607a2dd23b63e6382ec1e6ae434f47cfcd1e7d96c8293ef2994f850a27ef2d8210a0df0c219eadd2376ce36a22db56827d92a90d5e2fa55a4154c39061bd5490ba29f8309cf3e2056f761762dff56803bbe0607faef510d023b249663368977fede0577944f2ff05ead4b432bbb07a7d90148ebd1e30bf1204cd9069725d9fdbb850d3d6fde5044da1b9ffa222d99061c8ae217bc5b249960db545e6fece3ea2faeefa7702f065764b326ae0e62f3b8745cb73f35bea1bb9f6ed4fcda591f4d84da0415a0552306f6691a64a1d0efc8ac93559a79e57e357b63df48506c12dde74f6ea8fc5eeb1846c394fb8fd0fd40df26a42e53692db51bb36403305c1aff797e20adb6f8f1721e316705dcf8fe6e6989a5c3da253fdc6cb5de426f1c018161d72e34e6791d73023c5df69c0f83d3ea1d097f3a7ff37720a66868f40d3b87755bdaf508086c7e478ac1efc0dc421987af6db9b2f096a7270de91f5b3b84ee6d1d268d581718d3c534eeffbe2889388e9930cb051b5752c1a"
	 "b1faf1e367866af7d4b37ba25c15a030d9a5f32bb8912ce853fe7988dc62aa61264e3c5a29d18c5121a605558b15004c817cb0ab1646138cbf6375f1a179852bc22d80b83891edfd38e25efcc0dbb78062f479a9dc792e5822e09ba3e0b8ef71c62ad7747dba8cc97707f31383baa93108d5c7253dce2395fa24d77c42cbf3559b5dc0235c0ce49ef9e3cc816598698c8f8c5b32abfaeb44f3c35a01a4f47421a166d5aa893aaba80e57eb576b838c95ed6f9d5b3d389a8f86b97fe629408ec7c7ba7fd95d7625e950c7324fdd35989570b24f2e1e24d52b65ed6116e728dc3a1004d3d8fbfeeaea1c7dc5d3dc7a029f97f8dc7f740e2386eb27e9793680d959821031fda08c7146f46e8ee47ec28c7d25574eb690de09849725e490c39e524b74aecfc68ff0d760d115b4d0a126609cef83b6c80731dd17f4a307331464953c6b41875b6e5fea328fd59f275e2fabd25717781cf9d5cc52286246ebc92527eeac7acc6e2652c6fcff405e7b4a78b8f9475f46bb82a68a6e44037d61de0df58a8b7a81f407aaa260f3a49c4a2641776404fc15bfb77573dc8728573a1872e7e093663842d9368e74cbe3ae547355fa101daeaa0f97dc0a63927e54ae59fe13aac4f488e938fa67a12876d103b4a56b6eb88ff0104330e5cdc7c6886b46545d523bfbfc88f40f9654fcd0f8c4f443a225b50b44af9674166d3de36b6ac63a150fbcda2e2511ae2a42fbe51c08f7238366aada5c6be8eeb41963c6a5374a94b332012e860d6cfbc1b8a4d5a9825b88a90c9a5f"
	 "5615ca503698ad00df2cd93467b66d9b15876bc49895a081959132bad2e63757aa4e5ff77c6f25dd2581a3e9bb8e213c9313ceca0fcf5f8416882849fbee576d8ffb9dc057eb96bf6b81db60a82b0e6f315a13dd31706c0e36f4f21b9ce977ff6700cd77db603120d59ad8088e121cc3c502e37774b098eee7c8244f9bbe0d4a9d0deba3ec22e5abfea69ab72cdb75a001bb53672fe12b4fdbdf7e82c0bb2608de5d8e1961fb4524dd1acc890361923fb691bc5ea436246428a70b5021f9eee2c637eeab574babde4c0d55f57925e511ff623af5c4224d3ccb9c8572179e2610b4b79817ca18ddcb5302151f9facffca96269ff5fbb11e48209e20145bdd70d72bae54f6fbb89a3396bdaaa3d45413e3c5bc672ab98dfbeb3274156096f641494c1c946baab7c388a16c71ce5009b32f45dbbe37998906570045027950bd758b7ab2f72c243eccf9551d539946a99779848b16cddf9f163fcefe1e1ebee3ba7d5240b92698ad56a036274ca798eae19b0dbcf39a1c0ea1a58b29dc0e3de89def08e6c5800c94db47b7eaef5514c002d687b4d99b00fbd44137f56557830d63156f43bf73db8b330bca0ebb4ea5d50941b758929722aaa5452cd4a4e00640165dfc35fd35daaf929997adeb4c4f7611d66befb80809dc7bc6c763879c3bcd8dd0fe6b621898717fd095fb7eb403b07591b931a8e16ab488b01acd636bf4f1e71d5460532b8a3b00d7353e84c071de5cfa25de685cb85b569e08d2f177727cda11f196b040d25c97ccb83e355db98c2bc14844"
	 "1ca95b5f612020bc53a81184ccd0c5f14bf6d9fd6318ec28bafe8d668cb3c98c56ad416007bef4a3ed9e12eafe8f9e7d87fbb02d1f557b497db1a2c0fe40ec3f23ea88332513c68f724cc8a8af6636c9f332a8e55c2d41fd81a23e92e9ffacd3ef14cda669e7dbe31ca08a5238c7fbfe7020933087bf2ce0a7489fd5a3becce5de09628234f60c833002aa8e9c9ec51f57c8e4ba095c1d054750d46d64041bb1f567a82d63bb5e88fb70bdddad0ed7572229e56b90e74dd88ca829f1ce8424bd24a0bbfe3dc3f77d244ee59f364b36a4b05fb511b5b0d7f876c65ab4233803543b0a68b9d2d6d45d292f91eb4700c2dbf431e40c77a4fcc3ac3fdf3a2bae3df35b6417b8f1eedfe84cc65a07c426780871d16ec5ed3201ea4eaa778b71f04cc1999587bb4645bbc43e365395e9188c85bd024f758304aee979f8e67d07636fea251423e920e2b7258580d1918fce772bf02ee66926fc5f9a3dd6a8c89e6ce7e4fc03d4784296df1a9152a1fc66050983a287e3520bf3e04d900d25316c8bd5ab489bf97a2f31f4061f895111caff9968ecb22d75cb9e5400ca1d0fb044acb4fb9cccaa4766cf6c63ae5a7a3f9af90d1b225067f671d85cdb4e2e21d2850f351d995d54520fdcbb8cb30bfa82190ab2071eb8bf350f984408b206597371736110114d12d79da4027f9a58c8fede63cf16fa552d2a956ae2a49c83b0afca3056f87f1e27bdeb9d14a7e5cf30550017a3233c4f386769021a853b971746aa28aa69ca980bb02979779c5bd29259c84911e2b252"
	 "61b92be669e8a731dd74edce66b6f3ab5944695efd57c0004ff637eabfbc02ae346528fedbf2ae80d420580adc4d571a37fa1397fc2b85ec458d5262c15620c88f2dca0eb1bae4ec39d67fef56ecbdf89703919e5a6767d0f77bf6f0f60ba21003d033c9dc3057df18d855a5801110fa9a29a42ce10a44a39ed883df249ccddef8aaf832387e70048d9ad6014cc17f9a2bf7146696ee4eed388d06a45f7bd7696e57500ecfada9e9eb17926b16bbd90146e406e281141f0a918c320cacc9d1f045ac1bba87ce8d1d45cb6303988d5228da6ad33df6d2a5bd7f265b8f610078e9db5fa3db0e08286e500063f0fd6860a11d9985226ad382a95bc3c3941d43378ea1bf28fc85749f616092d77e7c292e311337168b52eba08ffc0f76582710a1a7d33c55162b3c7fbf227a324e1f4579e035ae0fa17fafb1ea964aa977490b5a3fc16c75e1fc50a6d17e193345b71369df804c61a71bf60be4281c3d1f945c690368c23caab006f9dfc913dbe6119d6fe8349cdd424db7074726e8bdd0ae99e2bfb9b800ddb965c06e0587cd10108c9b431cad4fd10d3654a22ceac73553a6b2b2218ed6526c362df46cfa776e2caea0de61b9d5c0c74e03e299ceb2221ed0f30ffc5876354d5607c3eafc77f78e4fce5e0c7f6ba7d417ac5f0511e2635b41b28dfb4f2fbb73d351a69fff920b76f5687386114b3d5ab9cad056c88840a023b7e2df73f007852763570d38a966c8258365b014a12a3497f506dbe55c073244333547223785438372884ecd8b66aa0a794ab5fb"
	 "94b0a519bb3cbf01b43463c0c7fc6ebc67754ca25686002e13edad54c817b0aef64698637d18a4a8bba382add892f4918b720aa99b09ed2a6e02b7140f89e3e00680f37343d3e47412d04ef78005b8b9a23b92d145a8da9c5efafce374955727367a7f1a179b990868550cf960c6df6baf2cddda5fe3e689de8dfcf1474db419ecf88cbce9de7a58e9d8a15991fdf5361846273d195a2892fbc95ad079ca8153910984c4694edb4c790f430043c4019fbd96fe49d8afa5e7d1f6674e4a125bfbdc916b0d3819566898599443ebf2a87b1fdaf41378227d396d2d320dc5b860705bc87f45eba2b6473234fe054267698dba0913ab1234b46697c54e2b19526d1ad4b7e3eab40a413f86170fe9f2a71eae2fb959a021b0b43516f1c8a3e674f37ee235ade79ca296364b0cad5ebe8449e09b63a34e8711587f7f2fe6e181a787b1d3a8f30012ce9549abb834fb80c673c575a25d3c33bb6d846ac231f411dd6422c59215e0a267424c0c57e6c9bd5486e8b6327e9dd16b7065eb74ef91ec9204360b03d08654a4e418346ec2d4d21edd5608a76903494791546d430eac38178d158d61951de3c61fbe5d56c22cbda4a3d40297f7abd83913e8b483d9a80cf000810d90a921f453bcf9e35732d2579c1aaef4a6980c666e3b273a9f91d9918f850bd6e4475d8aa5cb616cec58d6ab6d70dbe2b0f7ad85618b6e60dd4ff5d0faf19dfdf27a9ee48cd7b2d6613e76f04ab6ef5f0af12966a90875816c27c4297a2bf622ddf66fbe7c211670d0c46c7295b93bd2f1"
	 "22568df3dc46e9294c7258a0b7e81b2d45979680edbb7ab323e4857d84306ccc16ca79c711144eab7b37e3437245d7b78ced1cfebfc45892791b9ac6cc1211f83e328ce3f57af3d89b5be89dd2efeac9d738330bd0d8d4a059bfac06d1ad73bf6d427541e559c3d16eb5adc4380c1b25c1b8a9097ce7eeeed1c5d6884dd1a32ee2bfaab8371593a0eef65f80e705b9b56adfc0db4c272024a71947755032a5ebc1bb346ee8a99b01b408cc0b1658a319ffa5ab2eb87e9aa8b3dd9d9d92ce3bc04e4ebcc011a280143927676360f249ccdaf7949bb23770a06ff5861661d36d761508f7e9ba149310d1347c3165e07997853d415abdacfae9579d1dc0b5990a05ae9e6dce8931ac2db9414546dc64f8161a64cf30b9ce8c50ef2a99775f03dfc2c611e780a5cbcc27cab920a87d940acd8b3fd42897ab6f51b29214275bd564c50eb7aab3ad19a2c903c84d2ed5a23c49c81d87cf3244505424332c917d7b671d4a90765b8953c26bb7ed5dfe3e93632610ab44296afee2b5c631fe643a0a78eb9af94d700250f5a82bc57d24825423f1ecfd8cc2bb0daa229670d0d9a4fb342ee8c9b7b16d86d29abc2a57633303b918ac78ea8d2672dfdd4a06ea0bbd756fbadfb0c09e2426a65e90ca829ea00ad66ca8c9e79b9aa5ddd02d435cb23014b1033da00381ddf2dcf408660d1eebd1f6c7bf5ae9fc3fe47e75ff7ca482716534a9f3365f5cdb48f3d59fb19d11bb8782ef96e394296594812e8a7da23a953f6117ce577e55f3d6cb1d3a4007dc7d252c7123a8"
	 "37be12884e54ad10757af405beffb5cff189133bb7df5fc009544b2d62ec44fdc0c1c8240d4413af5b36e031510b1f1537a690ba7049cce9df4bf4dd63f6987c513992fca78a1cb7e8d670fb43a52ea2ca2f49724e35397041e5c75a365b510f40fa9bd076377274d6a95af801981d71972da0a08b536b024f439c43d13902878798153ed825ddd7dee8937181823076f036caecec170edf1b5fbdd84e530bc50a7acc257bb9679d72de3f115602d18d2d12e6ecf4d3242ccbe9a71a1483e7fe40d2447ba028a76aa92c13516ebde90dc4d204095a554cbfad79d6efe4ec540c7b51593413465b929742b729ca688f67ee9d9fe76431fa81217fb135d0dd6ebc91904efcb0cb6dee22867e5ddd7453f530d04935f41575de9ca457da55b67791d2e8b83890b5be543366b92ba6579a6f19f8e82a0bd87e379967766e5b0a58305b984778c562ea03a8b8392e3160ea4532b6ce5de74bc8fa0e8ebe88fbd62a73d7106a309f5a5f5d7617664b015e166fcd87906caa80ab4eb3e62f73e527b5d951a0ed0340fe17bb7b2692e4a31d14798879788fed12413bac50e490ab93ed66311599a6c1362fc60da5319ad907c7ef7852985ce86246276a138379d2004772d4d9a989b83b3e780bdda9825ad06a4b3dcc9a9d4d8025cbdee7cb2e02ea1f77bc90bf4ae56903859025b7283ba6410aa91933466623b996e9ad07e3095e376b11a27ca451c246d5561501e69c6747013ecda44f8d1fa50a75572453c9ddecc07b1aaeebc04cc7e976915f5e68d1236ae2ff"
	 "dea4b9fc4f8e91b03982801e2ba604b46ad80f966838ae09d2734c6482dd16d7738cadc1276593a336e2ce8cf7ce48d1535c7865f7b90445ff3ab9e56f58e254115bc07710de50d7953238d7ca419013d104d90fe79794995c28f219c963d716bf8942e0cc5cb432aafce4afb42f74596b847fde5d87fba9adce5c17fe590fe58e60379393e521ee194fe063211d72c29d58f7dde89addb6b0e20515ca7aa270df2ef2d77f92219781502c49292c6c4a985242b9447521cdef5a52b53b5eefcc43e8036ebe90b51a3565cbb180ea1b3e3d20f63b8f420c2a7f01c475428d5f63c66f122654af4edcbafebe34970c152767cf623eb4f1ee33931a79622cafc70cdd2bc7ccd55ecc1e0aafde3f66f5414315048d3c5c51638c35fa920cfcf7a18ada48a589c12e4da2c801cb8bf3b182463707a17891cf296ae8aae6a8a88ee3d602cc1bb7647861f65ec1a278433ae08d8c8e63727633425fda0b86d78378ac80b1bc1a48abf270dc2b5ea71691eeeb979950cbe0ddfdc451dcf8e3dc657060f4c3f96512b21bcb228a966381efa94bbf5ff4bbf38a803b6aafc719a545e4d0582a62e81e6468aa04eaf131f8d2f545c060651e115032f5b3579fdfb95a2328f5c9a0308874630e840ae1dcec1b9543c36267a9651c94c91cea42a93a91ba3a054ded4a8343864b449e46abec49474e218c8c541b00eb0f8997e710025631ac28be3f08126446dee0cf61bc69b85e4fc021f203c796cbd2ca16ebc8fa15f55510a08ed334155233c6459d2d428df31a3f376c"
	 "d81a530700b3ef08631dc5b50f787d4efe2bf219bd17f0431803d9d946255716e8543bf77fc44a48abc70a97feae8398c2059938d39fb4ac5f7214d92bb89fb9c45b6d117fd51f6207935beb1a89963fb9d1aa020669bf809c21154c20e720aa1178ed2bc13fd548e0d7d01eb1d028aa48318a02dc7aa412e2ae01ff59a86dae40771ad3f48f0fa54b6e679854be00deb9938e37ab3a4c9a96f3b7849ac75b82619cbc806c42f4bc4feb1141f6a8391bf9335f643ce5cd2791590b28b19d03cca7b5cf702f10ffa0317327e828deb4791f71500f243be77a451e5759c6c711b38f8f62757c54d7fc6dc586a90df7777d8cf1c72f9c0947af005d770f4a74b6c9413738c3b5ab32306ff5b41a6446c2de3f59a27b79d877d3f05fe22d11afd69e49e59f35b3725a0ad126642f388602b7816abe397a9c9233cf7d1e12a00362306d2d9b81fddb279544f35e23a8c198930f75986f26e6f292ae8debe5da0a7a5b8add2be71efc78179eff7fa2a2dad35863b69e85e8172073f434f48fb03f7bd1bc78fc2badbda261a68f7bfa171c898897b3b0d4852920674b8d9ffdb37ce66c1b6aaf9b375253a0d74eba4d359737f7fddb42471969d81605e41f615399c5fd6cce1808e9b511ac54f75f774e84b00970474f5136447af04b4866ab6c54aabf7a247c6caf3ee891fecb14073f3cfdc7368ac00f6b1c9b23e301e49257840f949a57c28a95c5c490bca91bf979d40403f7b9458bd255df757e6eea0bf41d5175548aa46243d98f2f0f6c754d6e7e58fbea97"
	 "7d7e0af8b7d0a6bce07d0c483293868a914a50aaedfb9b239b4c3c472381535b287a4146fd52e7bf882c9c3eff7bb2fae15d5b96bb1222d81d26dba563ac550e716b6c08b062cad6702a33a9db4274fa2e81af815e8325101d5a9ce9b345e29619da9e45dcbcd7b0935d7dde07644edc6b049eee9371511bb2cac50ec1170c7aad835c54fa52c8e0a0e8446356488e09c2f07b17413a7ddb872d05016aba129cc36de609831863747310f0fa443480a47524dfc5e1f34eef3ba2fefa29e596e7fff86a924462781930fab55e71fc2f06271e62878e51e0db08ee5dea31f1d2afe9a4f548ad6a4f4763c9d0eecbcdc32323aba1c9c12554a5cfedb5310b4a03caf426a80d725fabd557493c46f2a174aac851d3d39529d5ad919fdb7fb0dc1e5b0ffdf706a9f5af36fcd2bdde28d68c5af4a1da4e67cd44f97b555b62b39cee1274b7c3dd3971ace3da6101c87f9b8f28c5e13d4066a3e63543825dd8bddc3e90b6dc75bac78931da98929a337817f68deec6065f6f7883d5bb10cab909c9945f71a672eb2cda9fadf4a8d9da906e2a5d1f589193b4e791772663f1bbe751498bda065f90244391169d80490208083de39bec984af73dc99b10d85958f372004a03962c45c531b347851dc5e26bf7bcdd68c9b129524d6734282bdd431f991170d6a5c67138a5405d8005b355ec7ce95496a8e98782f6d978c42c30a17db9c12671d82f2d3e257f66980f20bb6380303f1e89b10035ae7bdb3e55d31f2d1574784aed5c95aa09aaa9614989d957a65d893dbd"
	 "abbfaaf30cae0cad575e39f5311aa00a6979fa52ec12dfb2f731a3ce5f8b6097a612c2ce98f5898eb2d1780d0cf9ad30ce5395ae871ba7ca6a0884a13c09732cefc5aed9d7a28c09041cdd62e75d7396432545f0c16496b7f5f516fb2cc603c0ec10a51ee952b7cd0593ec00dddf67e27dfe3f0cdc5bf737170243a8ed3c1f59733fb47bde4b6578d7ef11f95790d4c678d95ab2cbdb1673d2d516c189af00f996371077276e672f1223926fdcd6627ff86816906edad3aa97e3a9e7346562add05ec1a94c2dbb7f3b28ef537715a1d69761bfb8c2092e608311af2f79a4f8188665a48539944374437bcff6e59bdff4e4b9e4dce11307d892915071157698460b9e9fd68ee0d1acd21434810fc8ae702fb8dc794ad5364c79fdd74c8a70f390556930fc2a23064f36411c626179d1d745d4875f5c2b37292cb8ba37bb78d419f05e9a5d2245a38da20b6b14eba2d5ca3d58d23bb5ade1322cf337eb75a97ce98c167b6305907c3fe18038bee1e2450c3095480f99c9f12d2b543b33866e5546a39d539c6e2d639356bdbcbdb3b4e0935ac76e0fdaf54cfdf241d2c5ce135324885f8cd69e6562f48979352bbab357c6861c66b4ff7d9dd5d32a8ab8b6e759a2f5ddcee847fa439a5f9e3989039aa60751019eca6c7dfcc2464ca4a1ae12f079d200961797cb0e52cb046d1f0cb1d97c4699e07f019b48edd6f4a71b99ba26c2e5e72745cd9bb9a7e89d8eaba646461bb76818fcc447de2820196e32cdcf4a57c527c52f64d316b513f6a611c929890be5b0"
	 "3b3d3352cef23bf86d0e058b1cd9c4a10a9a01060aa9c9cc4bf42c7c6cbb677724db3f0c3736461c1828e67c9916e953057024371bb4ad8995672f760c47574bde9df9e73af90773cd46c9df8cb655f8c37eed8cbda40da06304471e32bc828a7dd9457fbe4d63a15633009c1a9f003f3db7f5b2b5e3b22c60f747d5627bce3eb4398a543cf24b18cf0a56728adcc253d7f5343245c1426b5bcd9daff94394499cb6d7ac2b4e63ec424c66f5dbceaf877fc13f47e744aca7d8b5d89c8d5621f4e13488b141062ee04c2312528a0a987a5d32ebc6ffae45657f4b2d1420890970e363a124b75374594dea0560320b36133e31d6a978f90ef079b81484503c7fc3edbceadfc9fcea06f271a60ea6c5d434b694ace1b506eaf013aca2c6103acfe6c565a5a24cdf638f8ee282ac812e32cc2662a8e2d4a31239952836c4896870d973bb65b280f0370f4c3a54c7f4723b2bef522ca4c233d7646da3fdb9743e273afa1e3bfcb947eea9f323ca908bb4961b214aa906cca1d2d56eff25d60952cc5897ee6390f9af4efd5d48b2aee8734cf6b8042f2de75b107f8d135d9a63148e88e43df815fe7871a354741f8863af4e114ed0369515bca104f8d3b24a2d740b8617de3e96a23*0", "vilefault"},
	{"$dmg$1*20*f615ec6c463799eccc6a2dfbedf12c6bdc422a2a*56*a595f4a81a490e7aa6378034661da57a424f922c971d3db3f856f8d54b0784bcc5d7182905c4237153c5d250b8aee1d26410b1dca7b1cb73*48*74a060efbaf2c79d5523219d8162c425befbb2094fb46e7ffaedc7cd4f192e6f0c47d8aa91e0a3201346725d3ddadfff", "vilefault"},
	{"$dmg$1*20*9c82b419bdac1b3e6b71f8a6b99a7501f34b6950*40*5da479e292e0acf67a9fa3e24d0a767cae2f645ff63836665068637188f4b80295de79aabdbc2536*48*9b136165ee73418631ccf28d5e77073788ae921df596649a7a7789585db0f13f446d5927967e2ede20ce8a4f5389185d", "vilefault"},
	{"$dmg$2*20*839730be2331c69df4f729ffe8a10c26653bea94*32*1f24e25712c2d70d000000000000000000000000000000000000000000000000*48*3231e20aa642889a7e087cb87c84ba1cd52864007cfea677796a6f52e16b2609696dde9230aeb5603aeb1f70f6701be6*14*8192*75884a049d2b7a40c14002ab6e511bf3c73ca79a2bb8285a3d2ac1d5b9b0cbf92d4a483fb762bae8485dc3fc9cd7a54141da2b74a86ea833d253d56f52eecb9dd4d40b9f846690378cb8a5db74fbc6d756ef9fcdbb5d21805ed43a7fb45d6caf6b3d2564f4a7760030aad69ed9e56789e8b2699bebfaac3cd73130fae1d8ef7f003e765e86eb84e990f3c24780022fdff3ba283ece4fa8d31716e5cb1ea22e408431eeb2cda1460217efda86461e940cb10ae602a84ddd22be53064e66c0973a04405ff17afa020b24f1bb4ce42750b28cf4e98c4f542576e712f3c2fe0a0539a411290f65ca763a94d865fc24b1beeefbb6b055db453da38e62bc383e74b188b86c54b62f589334de8ce3ab2e4643f76eb4db95bfc088bea8c4e88cfccd19b89b818fb698982f73df634c8a8148e4c8d3ec2dab02aabcf48ec0a78686fe0b4f5e589a067d6c54f0732e559cf9db5b4ae1f0468f5681226d3b03002cb6ec528b96470f1d1aee5d3b51b4c5f45a2702830ea35056e02279e76fdd30b3ac174cd91b65fd6a26a192f6e632b0fae660d0861059a62bc512f610f4974c22993bbafa364fd2e8eb53d07244d165f990c876320d99070fbfa6fe7e0ca42c0ef2f17205ca"
	 "7196376d4026a8a93fa83a99cd3b6cde354ed3122dfc07ffef91c24f2036b0d83467e120b85a92fa04120cc8f7af3196adb6420f519c610983d163964b0cbd048adfb89266d9ccf9845cd17ed04accff9d106b7bfffefb365e97357fdb9ab2d0956411c0c73bdf235a9ea4b50962c8f258583899ff2c0bad6602e8a3c14f3c870fa14686d15aa17f5cfd1ddeecc7b061cb5c00db7d198d083a690ecee97a1b4b0251349beab744c4bcb53a4c1702d1094f6591ee5ae15a29271ee3d3d22f0f833219c3676236c9e9620a206ab6ab08fe5fc663f4f2ccfdae6e34adc68e59fcba5363f44cbc5d8345f184ccb38d52bc2bbe6ad996c3d4316ce644698bba6044209d108c698c3d18f4b64161651224cb015052d2e9bee0079b779d77b6623e9669c4ff99988bc612c4099f6b8bc9719444cecbc5f87bf9ca6dc30f3b346c3cf20cc342cd4d156ed67c8be0f1801c3e672bfdf2fb9e6c6f1ef3570d059405a8a0c5bcfcd70f7bfc1d2417e3ca205be70a5ffc9b4d1d123ff64cf72b20df25e9861e1da57fd1311451e542c25100c19d1d70bba2c26752e4cf1c59a6373fceceebf2b4c392a45e2cc7151f4cc1c7292720b5f0716cf7ea752a8a44cfcb7f638c5387a410efbfae90598f2d99cc79baa298e30076d5ac8a2094dc14d81953c09fca8b41f88cbca2274158b93fe5a151b93bec1fdabe1a6c67807d5f9d46b2a19ba85f9540cfb54656fe473216ee1922046c5b6cd08b325e0c25a420765a61e5f7a266c9e0ea1148f0e62ec65736d4cacef77940a0eb"
	 "24e93b7b656e3b591f5827e78b577b628da26c1e5bd7544dd439d15ca21a3fbe96d3833ab1bddbb03beb8f0fe39517958b7bf43afdbc68b5061b41145e151d228bb5e5220b31a86878be40060839855db438368e40dd6b8d534c5c39009455c0a783455b41b572f2864eed60e5dad80979b97efd6dd08549c154b76f748101396847efd56a97b82cf62a25e26ecaebfa35d545cdf886ecc22460cc0e2983b9da14ac41dd1e1dead58a2c29a85f6bc900268d755d1158939470c4793359b50da19addd3d8f722c0a889ebd8dc69bd955b524bbe452cc98834613ea48d7a73a9b93820c0ba718cf664d82a1745451a204a2845d4e2a846f0f18923ad0315896b1c1ac1942fbdcba119ceed9e02b0e707b28feaba44bac94888ba1a31670cdce6348d58d2072eb13ee805d569815fb28749c392d11eb06d8b1746ba8eef3313072fdb4685f1401717933fd18edbc99e3d89d08a4c7798bc1d724d6bca02a31642ca0ac6223884580c0be8f6508a6650b783a9ef24de3713f65fadcb2da6d68c4bbbdc216ff91ea7bd24bd7365b91087c14edf70dbd4eceb2676797ead7fbedae77a0add9d22a515e2a79d075958d8fb87aa62700c62df007abaa3a5e002403205fe04edaa4aac3da6d08ad9ba909974e9091148208db90f330b2c2c702521d4b1b32acc4fe6b7ffd9f96fdca05b6c404afcc789fb9ad8c52063fc0f9b9cb4116ee11f07aa17dff57b889a4f4abaedc51a07481c1e954d78ead32c6e808d3eafe7cfa9d2d4ab4886abcd2f64ba2df2d8d507cabfa8"
	 "d01f785409d71896461adaeb4e34d18f9b2fa38779f0932c27ba2f3f75ece12f6eaf7a0d728dc02e97cd44ff175b592b8234c3e3b5491726c58dcf0a1b77698cd38d861fcd549aa793f8d2b58d6afd1d9b7bb96c8936c960eaa7072c00e69f68f948ee24494b8152bd8e5d6923c8eb26023dc660d202e41663888a8e8550092b5e1610452c79069b3cab41a2e7459dc0d361ded09c9f1589999623f6deacf276eb72996a355e4f7dc19a5217e9dcb2d6a3e4679bed9f980a5dc8f24a1c5f4eef00d706566e12ac8deeee964ab9501be5e57e326a6fcb794e4f4fe14922704206a343724913ca2e1d26e3d83cf994cb7aaaf9a916ea6eaa06987a9822c5a8e556b16ad72d5f5640b3490d6b0f290f9f2db7c3ead435e534406dee40366efb98f0b53930a83ff9bad177b84343d204a1083801f1d68b3aff78ec4246f670f924969e4608b419ea9f5aafec40d902492f62844d9a83d65f38af2531b875b964abc781b3537c708fe65f70a11552990447bf6db287412367ca918a39d9e2b2e228451807b01174afc33f5f67d45f9c765015da6abd318c980fc8bcba60ccd5193e7a8caa54193aa83bff7b77725be99780da88b3209a3cec620c17f979fb16e640473b0d98a2f492702ab99f2f0f83bbdcabc2a6dc4986476f420f112ffbc7bddac8cffe59e82ff558151b9160e2f99bf37a05654253321591ef31d01b32b8d69297b3bd57f127e9f574fd472b6d29b6e9a0e1fd43252bc1f1b2c8c959f3f4d80177b4fd6a77dde8fcbaf1eabcd5e7f6d38630f35d"
	 "efc161ba7432cc9af6bc73baabcb343c469ab18e4cf88eee21e49311b4f20077bd6e30705338f047a9c7bbdbe4dfa6d7be3a827c92823a3c8f36909f9e4df4dd91426b75ac6b5d953357929b0bcd91ebd24e651a855755edca82c4664d3c89fca6001ba88688e5ec8d5e5c3fb145b963b29424192530601d74e3b815be85ca44640ca89c57ec4ac7084639b82e23f065ac561779c040cbfe63310ec846db02873203feccc3f88a28fa78d8d567905abc9f8f561b4a29ec5c380849ada42100c15efd3d73fc203e63a315cc27b82f62c4ca0df9ea213dbf7eb39552fcc38edfba0ce7e25dd097bfad5224369f1d2a175ab88ee5a3371daece3342e99c60cde76a1ff5dc7e5ebaa7e0fb59d4d088cfbe7704126b2697d62d7b82289a35ea778ea4ca347410513513084f1fa971686724761f711a916ae1e92402ff3d52f948fdbd9c1d961c6ad6923c8ae9cf3a4eae7a9369daa5cbdadfc786e873b90ed1e8f5933ebd011081ae7ea236c11f0c53e00c1c0f9206f91e6954123b5caa08c7615a787c1661dc17f297c8ed2ff6c90dfdd9a262ab5e9a4489d6ed7ac032f72bcbbc2248e7f1675e2b2da0bf85caf89921fcd8e78403f11a28970f673ec7adbea798b3eff87fec642ef77c15b3f3d19dfeb74d1ef6a38ab938692207133aaeaf722aec4f6082a4cd742bd37fba0f1f83f01cd2fad6a169c4716940f7d74b8f29001f406de5897a5e5d813b995df132cc57a5d9bdecdad9024dff7dee8b89189d35085a70bba2e5e0a8c1c71cc593238f3acbd1337b2c"
	 "c5a8647ce6bbd669eb939279d3b964d661112752bd7fb877c4c6ccb5ef72ff5446410286fc69347841c5595a3408e0c73fed8984d0c0fdd2544a168ccfe41386702f6ab7b3675a78b57f9782f23e0471e6dceb176dc9eb871ddd92dc0b86b2a11293523189c75019200a45213f0cbd86823f65f28cbe6569a58512dd469431322b7ca5b9b8ca57e56a139dc4788ffbac10fb57441f2435584651fa572450a4719c8c9b4a322f3aaedd3693a55820c725b63096d3f211d830d39aa89be83d59b13145dea9231266ef6b1eb1fdef31203922308cff81b166426d662989a350ec712dba14ced58df7dda0d0fad05ad8d9c6b247307d481f79e6a3cffdb2ab9b21a8208d6d7faa72b6f22a505d2b950884474862f6f67effc81c6292f3550c4e8852c39c52d952648b256e961d478c0c6979300c5188c490ce5c1e34ff6dcfca63c0f0571ea616651ef6f9781f2d355dbca208e56948ab9e26c5d2d3f8509952bba3e93241837b11a89caef6c956c9354ac10425a6d8d4e82bd5d7411d18655393d7c542a7c914a5ea6aba717a226e0f51200cc949f38c703f4f6ce452cc1d7d6ee8acf26d34f74981f6850b11610c11d1c5e6689c1b6fcd6b6e997ea145851c6655560c33dcf5ed7315578263c39fe6a838c5de867f1b3cd482c0206f56ebea0617ae25b3ca8d7e13849bb2b58ea4e21409762d549636bb7cf5ec32d3216d827d94cba1f36e7632e3a43b3203fc596cdbf879d1aaee90804fa0cbf46d08ff4c40aff8fb2b46f7ba8ce21d17c2d3d025b67702054e"
	 "9d76716fe7b5c9d2f43036d86e6a17924d2f160f91110ed1f3364a1177aa6193baf59878ec84f450914faad409618bf25cae17ba5545abd33833ebf408990fa4236d322089aa42eebea965e59456250fa14bdb61a32be8d70372891a83e7bf298168c5431e0b326229c36c667217bedbf64e3a07019534a087e84cd1a9cf35a889d9e65a7be63e8d638373774148e127b328734963437e7f00253d2fcce7bc0d798c09326ccd4f379f8a29f2d308ab2fece6fcadd653b1a3ba53a078e51a1a87e8dc03c5c118444d82d9166c0c4c1bfbe8ee09be6f8cd497a20132d4b6e1edd13683b363dc6587de2f11cdd51674ebdaafc41654d639b6cdbcc040f5889efb1f64e1b873442493ebffd8f867f0e1ba2cc629bc5239ded578336a9e88ee8b2d1b71f6d9303cbfb8a35e4015d2f9ec25eb4618c2ac17166e8964b68a66e60cb7b464e36a2251243a218ee542dac96062ec7db751273435dca23bf3e8aaea895ef1d6f6bdc98fcb6a9e0658dbe734450682cd1a3fe16161a9fbd035270fc86684971e20f1f1869546e1b77a481774c9449ac6499f376bc3c0f0efa589abe3bf676fb385ea50618c681eff6e5359678f078292da285c4b5e66d5ddb43499abc3558490aca6481299c351c6b053739d0065c187f59767e7de24f1b7bcd2d80d0ab2e7c789a9f5172a8411a88d2c69d8f9d2744ca7e42ba8478648df29919c23c0f4cf14e2428c792f2d8abae1073b97d86c2d5cf2e5beebc7fdfc449ec3804a81199d6c4f24d9b040bd1feeaf141b7eea626c1fa812"
	 "e499b74e86dded2641ce3e11a04a35c8b8831a4de563c3614b4048eaa656d8dea460d2c46f6d748be434718e9f54934804756fad07d2a8ace694bccbd7bf2e33c09199a22a98726d2e1a690b2a9c33e39c8746d8125d93f675c571247b0a060114eff4c32231898a05e3ced4721edaaee9ebab9b46692c65f086d9fcd34b86a499685010ae0f4423625263d0a2a62672624662a6613bd4235b7402573af1b0571c364f7c14e277b84e4a102b1055a1456b912431f9ce9e875056f8b48345ab09bf06b3de6126fae32e2bd61d2fdea29a2f3cb46d963fa40694c02657352b9b9918bc50fd7e26584e51ab5e4bbcdcbc18b9bc17d3efc5935ae5077a269fb8e912dfc91a2c287686590c3e2671f6d29365c044fac2c077fb5ff280b0a4d69eee3b9538b4c8a029a3360902ee8291ca9f1088074f307392b70a7a43ceaa07c47d175b286c052e2412237da3f6acb1eb6b1ec386dbcdf5b49d2391615788f401ec234b58b112d296b389ede47243c01a1a6d18ca5dd3f2646d483b97e41370faa1c023118a1d2006694debebe35046f6e5852952bb520c9991cf9dfdcf89e51fe29d3cdad6f1091fc7c450782f06b09cb8aed1e1f95221af7ad369e49ed672fbbf2d255549d0fc0398dc6b4d37d038a8dc9e8d9b4d6faacf3c5fd10663107cec0e171ea6e1c26eb8a1534646e0813ab0fb449d15b4865eb2e9914d404d06c1e284f66e39d09e99eaf7c2f36997ac6ecb9197f8ea7fbdf7da38e427dd5179ef265f1471a096fd24d8ea2a2ec3b820c54356cd912f06"
	 "9accfd370ca945e60c72b5d479b15d52a5c3c4423c73f4ec06d9201ddbfdaac2e304b1408674d40c203ed48fbf4b126904900349228b28fe262539c9a12270632f28241198381c6e7174d275227c99178ef4942655ec95acbc19a3b96fd1e07b5e0e91488c979e7e25be5ea733bc3171b2874801157c83a6de754ecd05cd78d6d2846e7ce19f641bdb53075dca078ad0ddfa871c16e47da96d007b5e2b2854d151dccfad21875fcd12df56dee7f4aed6a54fa248ba2721ab2f58c1157c85a3df8486f99295f2c9b8e8cd7a65145b69ca93d0ac4fe328e31c07bc1d0af2db886266def575d74be200ec9a4ccb0213743eace8d7d39f810e3877876082238d72c375a5cbdc4d7de36c2ad90904a173df80195cff86f19a0904d18a1f8a92cc4779e5997dacba58770c5091dab5b832dfaab2d0fd102b99e3b8a799ac6e7357b294a31db5f9bc3d04036a4a6e18dd47dc88b0f07e1c4271e5106f329731ce4dea9f56f6d63beddad788d7eeb955589a13990cbe3454b07f63477642613bd77f3bc5d024dbc5c55a0c7426ac7cfe63dd2da9f0d5a7e816dfe5856b646b648c302c16b50296882c62334c9b8e56ba6dab63a9c787fa153d04e5e64503c6bbb9bfc8957d2fa607ecdd3714123dd52b6f9c1a3a73f649dfe67fd7195857955cb8c5470a9f363116cbb580b793033280dfb63ae47b384e6aed677251b63a7a27447f37e9817f10f27c4a0560ef34c0255617cfb90769aea2e5971077cc89022f8a44493d5157ab2962946c7fe600a24f002cfc6108d345"
	 "469a65f2f29b55e4da3f4c767324f173a11567ccc401628f2934989b29875ededce223de3134b7e99384f94436bed28329daff8da5690984b491d43f14d86d5a5e783545442f913dfa39f25f6360d2143fbe4c7e234a40f65b2c48ff5835c3fab67a92d0adbac9e63993db052a832b1c7b6045a495b82ed0d7f1068ec96fe1519493f7376a9f9f331f6ae89420fd1b523278df3e78c7b957f599767057113d5a1895801f1fff1b7021fde8360c4fc1ec8165132244b680645df7a1c0673728ca6323379739905856537091dba18f762b7be6f5f7e95212c402b005d73dce6a7775e90093f927edcf0d9ca24d04809f953ece372414d5f987ec2ae030dbb547db5ec17bef47dcb097fcd2fdd873eb93a99e2209425d4fbb589530fe41bdb5daf8ad8f83e48557a01d2ff6b658368e39bc8324cc2756160cdf56b8d7fe231aa03e82bf0b3f55eeaba71133a6bbf72342727a52ff7d158992895c61c0bab4cfe42ba5e4d5f239ef5efb6433dff84a02e2a5f12bfc35c1062e4103a3f8fdd1c5be28bc83725023c8a72d2cf5103a7c97a23b2d9903a1870726ad2bbaef7b7a6dac3e36c1b92769cb3f43eea1faf95c53db0cda2a8bea38efc1dd11695bb5de4baf583b175a32d49f98c37510e9e56f3d9e10bb4aff163abc91a36f24fb38d33d87fb4299d5ceb5144c69cb741b03d35436002d7740c38753e284a808a77cc1d4ff9e63b9ece720e778497c25b46ccf757449cb3b3fa8e5bb6d5a9f6eab58c97e9469cc6192b7b31362453faac839327067f41f25ff"
	 "34c2cd40e9fee3a0b8133f266407587ac40db20e7d7d397e90558e54250111f540a44a70d427497b5a06c8ef87f6bba0082e00d42adc7eb38e890dcf5cd426c1bc2b4c781b07670382aa0d13e227e05c1987d3cd0241b5ad78387e19dfe4804189dd8a10cab05c79409b9414a6a384cfaadbefcbe8e3521fcbcaf52d92dcf1611ba3a824b576051aa24f42cadd7b7e9841375646740f2a6271d81d2d5f4819ae6a5d3f1feb6f7923f4252872c3a2709a8b8556b3977af8c4423bdbcf66ade1b3c4303539e06957e8930aea8ff70d6a202407aa44c6c8dab0232a33ff3f3ee9f61ed664bfadde8d294022da21b10e0aee583379d8dcdc078639cf3a1ee18d6ee1740bf1b917ff56070bf807b90d5a19f37a5c31214c6a19532f364d463595262ca057f5865f0d55636ce080acfd4e303f03372af014a3c32d2efec8f7f6cd6c825e5edf309ed16008e50aafa2584804c1897f6433e350cd91e155ac786dd9c3deb22a39d69e85331086842f32ba7cb6b4d4f13e08d90acaff24315020f7efb2b74214b14e840d739378afadcb06d45e7bcc17f2a03ed54d0da71d865508900334386ab96e11b88d2811c84539e4e2a93aa27d66620500789bb4d595a8b2e5972b1805d88af2b722e1e9b8aef10ca3dcf5ddbf3d20a6f101bf8f8a8cad825946dbf0c64193689f461bc0c62d138f902575ed601e26184a10ed9df17ad4be7c9672147c0158f132452ea502948a749b474cd0a63ae5cf942609e4864985b4060239d0cee6c78ce4dfdf5750b51ffbd5ee920967f5"
	 "dcc52df6771e286eb83dac1c576f1a073687411cef3701ce6de66ed17bfe0fa5f03c63f96fb40ad70b478aae1e16efe22cb9e8c2aa57d5498803d35fde7f920b32ec686e6091a9ba6eb91fdd17b3302b760d084bda32244f704e14af619a5c9e72bd14c4e69f51177a26174c16d2e3eac934f184d460df5640fd84c3d3dbbc6785c249a501203374c0d58852d52c4c64a6d70ead2af1bca1d61f6f4cd00c3892565e085d3e603a0586d176f478062b092b205807fe7438a065ae7dbcb14f69c92cae4000dbd6804bf4eabf112813ff0599a29b1fd8bcf9d0ba7d9b14e40e38826b48204d8c0a50fd804167c88056cfe77e7a75ac36b5bd049571639b3f02a7e973abfaff1327080630a4bbaf6a096005ca2ccd54f076f2c3311e6e7b48bafbc9de38d01c8a01ee41d25ff0f775a2db4e34566e377683bad9a133482ab87907769bd783bd170b616d48974ad332e3defe94a2e7d6eccfb4cc43cad93b53c476e7795a087fe58cc074b591315daceee3c02af54d9beac8162b70dd9863bcd7702b7c8c72022856f78b2d249cacaea6c1dbf1317ca9e35664c518bf4155501ae77ecc3f47be6e7151c4d5fe56b893c69f1f939cdfd2b68830d9ea47a89fa7b3d4f620e0909d5a97f2637e2eaf223f25fb5ce7949e3ceb87d93db628872fc469f58a749e8b4841798ef505ef2712a3ba713386dc56b83e504c3d24d2ae8200698f9b3eca8d7971f7b82dbd5df6deb34865e2e6336fcd2fc3ff00bf9c8d04992f012dc9473e347ac05aff1040f010b1683c10dcd0bb"
	 "49b7b5883ceb6c0bee4bd2ea6d275f884a37fc7151245274f208a457f4bcf180d793de68f09c7b03e7e430dd34e553362f91c4e721926eafd54d6c8464082d2d4a4c5b4b44495ddb06290f01913e68c7cd95963242df31741eae89eec41d0af689518ae335aae42c60041154356ce475ba0bc7f6c5ec798cd7c493aeac5e08d7ef554dc23832161a615a6b902e1d4f7bd076f3bf045360cdb73c3b2d7c158b74d2b718b95189225a0824a38836d1d4dbc5a2861e62f8a8c2723cbf1fe8951860f0cf7b4c6bc4c307cca509435e077f3947b8fcbb8ba1252b89d61b69b0328a2b1c31255c2c9df670bc244af42599cb5982878fa363627b321302255f2a20e04b70e8f4f63638af83a98ba40c55ecc46230798224de084d2cc203841d91c4f049c9b0a98535f3f905bb80b24679de883470c8225af80361031354483d879f98b78cdc5aeb07b371fea8355d146f9bbe16c9178f3d83ed63e2812048a386ef85d6c35ad696936a008a524f358ec8a2e40081c3c50b73fcdc6199f59e14b6ee213a8161f675d5938ce72a848ba9e7ed930198d9ae6c43dd86d94d88c5312be17b9dc590072e382607390e247869674ff446e8c37d89b7276aa61b5ebeb0ab18f500389a326341ee13283965dd4cce69b666d2c114372cb0e5b5d9921cfdb5e12aea0d95ec0a73c8d07b3b3e0dd8d159d323feb4bdaf6ea184bc2fbed75e7cc13bde26aa597ea7eaf0e37aa4be069c2c629af7debd8692befbf74d6c9939165e3238d8b2b573001ce957942b199e5c57935ecf5ae0"
	 "c3b161b96f1f637605bc29bf5230fc65524041d9970e9b4bd6e7469e0c0bfb62e672b30a7094b014c27a06e3982d83a951ea4207a4d7b38eb155259b847ecba4675c3f82c48343a07e2d5fe16d3189c8dc0f4bb1fe2ca4abce4638a4462f0dd79d69c240eeac8ee4bea297bc1bd5683ca97a352712bb4461fd507f9125f895fc7ca8fc76c7f78207224d0fd142669137ccbac0f023fe1700eef77abc804e9b9da27ad5c3a767202a0d0a36f8fe86e2a8ac5f30303c39fad8b65a206239b881910f9d904f96edae31e4befce7822a7399ad06355bc3c7198eb1a4b2c7c8b4c92a604dfa4905109c35edb62dd3c817cbf5261f5069bccbcf98da9ee5ea192151237b31131953509157f833bb1b482cd011c361d768347b2d0da11b1dc43b392d609f0c4806d7325e92f9d76ecd278fcfb9d91e9993addffa55d66acf9211b7cdcf28c73bd4e7cf83a869532c90f9880bb963cec69cf40e117b3fdf9c0c5c9d6570a2458aa9d14716ecb8b6642a4cb1fe0fbcf8298ad0db3c676b9836910658f03bd47ded56ed210cb1e2f1088c87f4e225faabf29e2d450468ff6614f282e15b4a6fbcc9463a16f802d3ba071fa5b009403478f1088ca8a8d9eded648be7394aa6bb3590c0725ec87fdcc53c4d2afea49ba11f9f2b3231c912bdd9431ad941a7d89f70d8e1669e90553b047b5f4a033437fe3b84c05105227efb5390e6e99b597fa1c35a1940f513ee8aaef9485d1ffdf7ce94fd34dfccfa8f178dc113c32082e0345f6d39294ef283b6f9a566a87b1122e74411"
	 "8e643cd6a2ecf14e47d68254d26942666fcf957586497c72c9e5814ab3371fe4b0f9a7fa1e5d9629d0dfe9e93fb388865a599076e7ba983365fb3bf574d335787416c099c545feeea69e3069d841b62e4db9833e6865e24cda78e2bc46ee83ad5d79bee507c44007200e64b5d1329930bd658e6f051cdefdf758e5b023650c2abda7a6827ca394c086057c617dfa8c161ea1f953446d8e0d5f6d5c76bedde8d596d1641a973e2b53bddb8f7bfcfbd0fbe4883f4d6d4e6f930e51d47ccc40148e6ed1b409705e9a777f1bf86af2621cb1f04ba160a5faad78a0949032e9dd7e34bbe6b2fa1c478a990d3b7c474a2f81af7f7246bdcc669df005adf397cef71869237c53126d1301ceab14011a529d4897cb00f7d93f35031facdcfda8110b9fb5d55a057ac9087a9cc8f1034e03f79a806db8a8e726e8afbfcb2c7c39d3315ecad3a2e542d94753b88717b7791c66c47a45f499885f6c096cb1093d9dd6082ba8eb2132e4a80e22ee309b7f74af55530e190d73315023fe4b52fca855a06fd111fbe1125910f4ace6dcf228447c007cf82fc50993de0202d28aed32ae795d2d75ba8c975b78c657af*0", "vilefault"},
	{"$dmg$2*20*186673f316ce762e8f2b2595b3e8ea204aef584e*32*df036556654b76eb000000000000000000000000000000000000000000000000*48*71793cfc457320157f12b1351051f60e59fc80a728f82f0156cc8b3f20f75bfb4289c65e6c8c21589f3dc6187540551a*2*5953*3c25089e22f54dfa868b7460f43185a32b6988681952eca4a493ff4699e2340f8cccd06ba2df28334dd01b83f8bafa3754b7afce8f859ffaf64d33950a817d5ffa9671894f71d6ef35aefd00d237f7f8f413b8b8424db42e6fe7bf503d1d4222d77d5c3c2a16f26a1e15d7797cedd59fbeb45f70ff7731cf8be628895f13cc2937f82c92e0d5c6b6ee0214c668ad1ee4f41501dca668af0f83ef252bd6b6444f9028f12ce15134fcd8610426b5a6a75ac25fa938f93280143b5c991a683fb008a08e133a962dd4e3aa9ddb57e72955e3a840c3599b84d874d61cff4236fb487e2a344ee3311d30a531a20ec800ec591607edb97599b297ac67e173a4f7d98ce2d73b66c37659bc75becb65b799f0a1642a4282ad623ee574091821c971363128e307288b4377e1e90e831b800936f2b5eb05fd5d0e505d71e7e34311950812131c5b742ea238bcdfacaf35e23a4b5b9ee2a7c0da6aca0ff02595fd4229baaf700eab8ce7ea772e133bffd5665ea3ccde2edf61d11e64dbd1919454f977a31292416c86e3e11b762a3c6f0c27cf1a07ba3c4197f21c8959e0f04fae6a086be6e77b47495d0cbfcfce05e34ef361d45b1f8c5068f0174cbb2ec9a9f37eb6ae1fb0887"
	 "17630b97bf46c801ca598878e6a8a96b232266479925e8f170bf76afa4acbcc6c7daa51c2b9a1821e5b5df170a8b57aa371019c240626b2f2a9d60587c34383ea7c12b300fb478e2b62ca9bf54b00f04f4970a68d6689c4087713e9b6be1e7c92ef16a7cd527d1ef33140d8d3994c07d8ae237e047bf478f164aee1c6300545bf986e570a403ef626c5fd14044611621bc5d5f37e417175a22288c2fb45b0e11e946f755fccdd774e5ace72bd2ba44be8f673235e9b49c0fd4d6a912493fa797bd97462de0402f77da7eee2ea6c0d02fa880ba57390eb1f73927d4616b95067d18103ad4b10af7a40b35e620211acf4c9f47fd12080b2df1d350d17afb649ea5e8a038157561b107e7d1d00284a59541c0b759bb424d2795ff1d3bfd7749461a9f67502df649d2d69e72036ab4f8869c7bb35fc999a9179612524e2f9bbb00e7dd5ef8fbdbfc486447ad5ea93b7220608aff49eebb98a1de88c68ce2b9846a63ac6b8878fd645bfc0c0fea6bb746b15301f58d2b9d2ace73828a623885fb495761be85780668b436fcaa6367776dee9e3af641ed5755f1cca7a931c97162f6879c7a3bf6eb47f98590d07654be8fd8582c5774f89bebf6fb113d75d28afe74443a64af360f41b9d243d8fb865039d924fff4586e3c76d9d0d43f8487200e802adb9e01460eb6ad5538d8549999c4b38c41dcd878b8dbd049b853aaa4426e74226fa19d3d501e6a93aa99dcea681f0044e15a05c2d08ae49f625ffe88181d2c1fe55e91b6f602409fdf961af1da851fff67f1e9"
	 "c9ac10dd3960f460bb8f937ec415870cb9e99e150f5b2a2308f2136960d199ccf5900f130a3f4610cda347991cf34fe46717071dd5ab2e8dc5bc20757fe6357fa56a18a606b25c51612975f51cad52e5a20a8eb2cefc79732fe19baee7b8c65167e2949a4ddc8d1e262b47c97286c2d0fb7078b3f553453445053d82a865320ead1ff4bf4fea84cfd7ce21e7aee696a15f92da1f3d73c394d47a254247492fec3b6582c94cad0df1b1b097048c9c91bae6aa269f5a074b796bf86770059cc767aa07fcf84010b1686437042d16d693775a03d9832857bdde9f7d98392bbcc579db3bddbc58d8cf08f04064e3eb92d87829e6617efab245cfbb6d564c5fa333ef560d6105c525e39177ff5530dc154b691b1dabf14d0da99229a04ca5c6e7956d474c0ee578b1b287b0a5971506687670ea848820c44875c74e69a79b36eaa3cc2a5a27fd5098f0fd3c190089736a271ecf3f14b3259cab95b941bbebfb5be132d875328a1b0ddeed958e8ea454ef80724f878a2a690bef56fe3ea62f47cfb6db303ae608957dbbd57735195d6b1b2ed73e69d1ac4b4b4fb01c20eddcb29e8b44bbd71fc25515885a56b8b7e55edd4c21d5e8cc43417e94e57cc49f279d0ed740b286d4e27c0b909729c4250ea2d1857f3f7d801a87afcee46f455f8a53e211fa0a311006cdde262ad4bc47941bc52db89c4b454b7075bf29d9cad6c98b7e84318a071789a78d1a83ece7a24cbf17691aec06c5fb7bb8a832c0aa33b27a5b3a68ef36364fd85cbd19e8f75e184c3d1cbccaf7eb"
	 "c71211506021ce0d38bf8c0885a205d7f4a60f7fbc972c7e2365b07d5a52fe8ae02608c7bfb1650ebdb4f2620f2698f5fc90c7b42a34a31732d2cdd12a4bcae3ce399623211946f74c67c5e82c0f53701bb4460504e17c1d6fa14288a63d97a86068be8ec36670adc16670b5cb3c09972b596cd441e4bb9b50471708bab77691417517e91883df9f0b353c2bea3d0acffe5410097edd2b3886592cc70ccaccbbf64d168637a8a3fff0d143e497e5311a9b13b4adcbe8d2625dd1fcb5ffe9c83ddd4a1cb3046616296faed945fe7b29ab6f912be6959f8768ce28958f2441a1e161147145a1621693b9f2d24fb9c7a89535456dab48dbe15c689709e2af6a6805edf923d8504f3d2cb8220ff9966f854c84e9ff04fbf45e42a5c73df4f719b9ed287695a4a03d5c0a3a964a7b6e95bcfc36a292b23774812e8567a02cb8a5baaf89afb900b3fb7be40c9e8432656307fbf2487c0d1f3baeda11e803f9f298e7e0c478f9fac11a43ca32e2cda46ca6491cc7b31aa1725d24805587722248dc326cf81fea4fc1ba9a58bdce9e34740e3732b96889b36e917cf029c7027c5cc985f8b3f0fa4e504325d56c7e653ce903e8410a6b06a2126b3aae2030404441273c1e486bc8285dc078c1874635e75cdb753a0fa821567e8116179b78039f8cc52675d538fe38a71f46792af445b125dcee671bf7789f2e874b25f05a431ce574a2d85762ceade5e5cfebfa5ff62b1ef5ee155fe418b16638c1562b29be425e05ef0237f03bb42181f55d4370272a13d5fbb353358d"
	 "a434519cbd0e4fca54f9cad4a7735238098d3984b0cb9360eccfc63b3b4339e0ad2b2719552085d7445681c919f21a6b482402c271e34d7f9fbe4fbad68eaf825c57d22ec0a2c5ddec8c1273131b867a3760626abe779e37ee632f41f212e9a9aaf26fd5cb28df689d9c4875c49db62213faa1e18c35b5d2df1fec21852e7c35d20d6df85ca2a6b10898b244da31dbb6de3a3a8553601c0dabf1e5f4755fc77c1561223cf0b1ee43441c3aa9d855df0831db6a7f6949ff0ae1cdd465aee616b789c268417de07e9c0f0ddae6b07ce5186b3b83ef96fa1ba9fabda1bd79986efa852a348364e33e89458550049522e64491a9b24514665af058b4be4ba690299d3c2379b25ec97575a9312b38d3106f805e829bd77033f4d5f1b35ffc7289c118749b31f17babb56f48aec597049d635c055d056db0434493a379d15010f3325690444e1021abd622d18ea7e0b5d5b97054708ea9087b4721bf857e3504aafec84516feab2a6f6309a506cd3e931ef3ef47807feba8ff0b6dd56eb83349d99be8633675eed19be804c06d4d81b0a256ec95cfbb2b6565d7906537c5adc404713baa8fc2e0f425c577660df47198e91d2eb3ee7a9a5025641aaa759e7e1f3dfd85c83a17a6a59df4af62bc669f28d12544254f4e0527a6b10958664af9378e41aa9f88ef3041ee6880f23a858254b5d0fa7899655e9d06f12fa863b63c2c950a0c3eae774149502f0fa3c3a44d24add7f9426ceaa21dcdc5408f0b96d63dcfd97dc4a3ce03ccd56c8d48ccb253e82d50123e8a51"
	 "76ae5d1b9cf6b6c11d2decea9f91e9ddfea605eec75391ffc4e01f4988c0ee78ccb3adb8a5e16644eb30e7e76ff251192fb3a8c48a68224a2cfee4aefa616ccbb68abea13d335a4b212b0b9841a42b418cf413fc868a842a26950e11061608a623a5dbd520aaebddfd1a559705e8cadf6abfa272925651f84130223b0056be28b618bfdfb164d2c5db86d82ac0eb2c457198a6cf8b0c2f2560eeac4441df45a9192cdef63a00adee0aafed7e0ab0bbb0c0b9a066f9f45f5e0c6a9376a069a45512081ee3edd2e9679d6c46d71e3740c5ada7457fc5d21610edccc2bef851d18f89e8307105855da15dfa749c44370b8149de48309f99fb5040d05d0739a64cf253855c185550339af73be6d5cc2de3186ff4b004ac816c1f4afcc83ec3ad66740c57b9cf660de7ab97b0771189fae5957751eec58a3aa6d3ec6121bf767d13533ff413c84c1ef47142f51ebf515c3d60a3c5cc3b9eaf9d43d2a84b94ce02db3f254862cf3c6330574fde5f8257c215c416ac3c9833839d5b33436fc12c21046025a4b0be90f18dbf002e001b8541b888835ad138def9910c4546fa0cf496bb4415463cb10004959dc6b0e379c18090bbd1aba6e9588fc21a89778ed1a1c0533049867569691aef6bc310fe4853e9e9bdd94a58943017a197526c70d2d278c66e94aa97abe5af8d9faceb0fd4e102bb69c824a1e4709be2125de420aebb11506bd62ae6b32eb1bb2cbcbc35dda3c992193086b11203775b33dcf4206a976b31222fcfd8b0e6beab7eed02f9f6d0dc2959929e1d"
	 "30c856a672379ea1a20bdea6e023fb7ada31f6f9e02f354f464b2261879372c0c92ea462ad11a83d54bacfce3febcafe14753d697e905a7c77031beb83076444aebdb99cd1aa470d5774ed91cded7eeccf7fb18860fc39577a054b17aacae86d02c2dabbd3ab068c982cb095d135c11daedd863bf9abafe991656d1f7773cbc05aa66c4c800b5763fe845d06c3b19f4f73dedbcd50ea363aa11e8274d541ab754209fe7fc159e7bbe317f8d9ba602bde8fe02171f8daf608bcd4663eb401c7a3f2cc814bd8fc195cc192d4d6fefbb15b9d9738f5e6ade7826d65b9d8477ef500afe2e40077b6ecd7d3ed78233fe980332a313fb2fe854d6becf9ab4c1008cb1b16a513d3fbed8036ddaaf372e8891c59c6e9bcdaf2d88e22d528b975d1a36af2fa792028a3e1161a74545eab1cd6284079c2353ef1c49e3e1242ea52d22d8c7d64f553e4c396e7d62c4a6619ec698b56cf25cecb6673d8a3a703f65e480f1b8b91e4427e9f1e9dfa1939134d03cb3115167567835d449f50cc9bae06adc68e3211d8e0cc1faa34f7bda6e1cfb088fe980397f4643e89052d2bfeb233ad81c3cd466bca1b1007e2e6459e3aa1e51f1a326a2f5d89407c05946b0dc7741f458464b5e4ceea5e367a2e4f0d007e9e31b24f5b7bf69aecdef4ef57de58719cf9fb5e8f5366452013a5bb69c3f1807d83e26bb63493dc141ab1ae8eeea11c495650b346919de060c4af1a80823fb10b4cbc333b9d6d05c6a4c293a7fd524c5259a841500617ee442222ef2cfc71a0e4bffa87903ff5"
	 "31898a44452ca2b132c4a633c91c7a24bbc885a01001988ab845e53a350c3b283dda71360c7a9b47ae40f72737ab6be068ed8ecbde1d0bcaecb729c5bea691ba0de6867e6e6879fdd99efec2b6de4c2691ec9031189491a01329fafb2f0d0cc28e26a22bf55be6ca866dd4a473153901f244c63967e829d9ae2ed83451a365558b697055a3b9a6bcb1bb40ae56f13d4b60defeb1a06cc6831e175ccbdb92a34462e786ea28e2ff25b813b63b30ea3b8d9a0921a5a5bf45576b39fbab6071fb1412670c936b5fc31d668026d297c5b84739021c4e763686e4011a2bb7e109db8e1d6bc853235a44ddd93f1012f7168ba3091a2a92a3e05bbc761fd97ebfa22265e6c1c2bccaa9d327d4ad61de87d3b5f0c5b29e604f79827064e05eede8b574c8982bcc0439db27b15bd7ea9a38923a1982fa7063f9f1572963c75168d53756803f6f60604ab33388ccc1294fb0ea143fa5e128a060da40f4dfa0382906b878a602c568f3c99809cf1d5912f224b2adfdcdda84df149217bf8edae18fb4bd825900ddc57ecca2eb7d209ac44e06e674c2b7c126756bdbad066dcf187344824050b16ff9414fe957c37a048c3a260a8dea72f7a12bf5b35e1c2205866bdf85367d94af939bf52a3027e2c560ca096a449b7297687bee98e4cc56e1449448461d028e435fef26f060097cd96bd605d5a1cf6b1cc95c49037401878b85d437ee43bcfbd7b2b8c145c05a33fe01226a637dd677bfd28c8acebc4a30494917c253957462cdd5a3d200e350f5d92c5c57bbbc7b2392e4"
	 "569610f35e3707aae8a481b8500dc8dcfac689a018671a0f3634d18fc7bf4f7c58933da452308e348a446ade0bdd6f02d29cd8d273544ba46f1767873717fea45f0e0980339fc187acb7045612e95db5dd9c89169daccfef2e3a01c4d19984f8b1cc960d054285119f23e746d743a0db459bdd5803fcdbfe92137e80d47c84c547848ae563695cbf113253b8a96e368bdacf59ff73c023d043348c1dfaf143ed13424662c2da644c25b9d22598813e1973f30ab103c0ada9ed247ca038a056d18f2e7c8443fd2c95366b387e9ab972170cd2b4438455dc73619ab3444da0d64b0b2d3a9d640ea917b1c09d17c37fd587eedab367235e1748dad753e4cbc74dd53017ba65571a5a65269666df0a24bc694a2d24e862830e7808ea8ffc1fd6cf4b29564c8d77d9692d7fd55e496c69f5f17fe145abc0dd1818f2cf6eb979c33eaf41050901dbbe5a49c8bf9983b1284fce92703b45c4131b3204fb9edd58b6cda3918cc490051bf9d6751b7702e577b700230f1820238b959e46f7dc3a3abad842814c69a76be5376c1e7b35e3ad7318b3439008e4c3801bd6754fe67cc7aed658d89550a30cbb1193eb5d2144eb7f84c5c6ee9e13947daa3534ad4902ceb9cedcae471547bf95e2337760322b55af97457d23d174b1c6f3e1d3585feb000953e298e35aeb467e90342bc61bd05af59c72921b2fd4795c19bba268bc6bf4f18349ca91b89cbd6814a62dffd4684ab78e998f7e3833b51ffc495ca3e789e685417a0d972bf4192b0c50016a64ba839da14c3c5bdd"
	 "58a74e96e56c66d73e2869323093892c5272aba5e6edff5a8976c5e04976c8bc1b8cefa630cd924b5bc7d28dbc67b8aac4d7571623c4d412acbfdf61603d2cdf1bed6fdcf8d88519a3ce3c4803317587c4a7dd33147f66aad06554d69138959fc3172298be9f5f83748b83c6618758bb45058fab1bbc1434b993890288a42910b91bd52ac1abe775acb09cf7173ff9fdf0e644ee94b000c8ac5cbce24d424800a9df431e03c650b3f4196115f100b49b7a41f68ce27e5dab5865b40a0977cc1be995d3504dd3bfcdc8db2a57765b1a80f6cdac0db795336bc9ffa4cc163df1d9d6e034d5b246cf59ffb2f81ec02ad4c48eb652be03c97a11427ab519d8fc8d704fea98d597e44cfeb168f3fc1385f1a1dc5926dfda78be4c3a3e1d024e4492e952cc8471ae1f26150cc065bef433c0431128c7df6c57bd79dbd409fb0684137465ec0687ec2ec45c6fb76eb88bb7bfb4df3fe69421dc7e0809e2474f987a59980fdd92b2a66ee31fb9560b4657a112ae523caec636642e44b507ed5a900fd65e29d35c89d252708b7f2c2daa29062b94577b0406ab9cda76c921694998192078e2ba7a90386e1544444c228db678f9c7da51a06b9c0a22ea26ebd3dbd8880a6e981decba2f659ddfcd15af8d06031e2d8ddc587417ab536fd4cef49372e0510c58060f2900e030fc894f1edb6aea502b0e2642a8cb1e0d22cc11a43cfe8eda906711e059d6e4a55959cc337dd54428eec2c123f5cfe185a78f442266f54213537af2f4b42176951bd9b0d1b70c61ef5e728acd"
	 "1a5b0c8f0360fc3d4106d1f1a6a100326500e25cf6ce2c7f230e5e54526c3affad6bba78eb0a275ef942e441919384b0420571655eff68e32cd97a322e22765fe736eaf329f41b2ea005ad56acb4c092b7bcdbf2bf3e54b058827259bac8bd94ea73e1d61cba79deb078857c63e255da3b8ed4bf5d4f603d8e3e19813fbe997afbd272102aef06950ab6daab60139fae51f0fa8b48f3e056a360f074692f982aac57ac3472539e7484862997ed283dda8be4b22b83235299d1b20df4ccbf0fa24faf392a8433535d3f3cc3ad7453b9b150dae24b8c78f149b53f5394af065082540b46f6ec3e70e2428b873fa564b548cc1e39fb406ff897662ac7e901384b3094c328bd484980c120518a8504511644b0616215df50ce1ab6106762d52ef24d40b9851168c69b3068682525f1050fa3ae139c9500f89d1b5a96c35f71e25f8ac229518a79fbdbfafcd67d7356bfc3e9699f0e5a8c9fceb068f810cf2c8e3042b5fef34778a3edcda569dde4fbc240996038e50e233652eb5f303fca7f8f29c633684566f6548bbc311bd24d7e0ba95da8f02917048d9777e5f142f83cce4187ec1af72b6b6c3825e38646f9f29697f6fe3b3cd76*0", "password#"},
	/* test vectors from CMIYC 2012 */
	{"$dmg$2*20*dc39029a22b86bb4f930499578d0dc9eee69398e*32*bb47bff69b10ae67000000000000000000000000000000000000000000000000*48*c4559cada09552ab075e73dbefa4aea1aa21209011946e423ca707753a91c87f6c4cbed3beae20a244d33568f852068a*6*4315*504c0c37c600618fd54da114fc0eb24d6f24585568543126ac56c034cd8d7b3dd991f1418d0c95791e091921c02bf695b7835f7b0da2c1b96524e72b4bd3f671c592aa176b6a58de77a35a26bd1d0c313b2ca23581027fc52c7c63f37439404218d720171d3b178125e6ce0646bd6fa1033f2ab7b6849b3a35a430cbd1401f73b5deb478d6d0f58364579c208c613cb2349fb19adaf98be2d4a74a6030215793fe4f1129189626bb87c23d26dc2af51a98e1fabf2f58e106271c7759d104b9e5171d8f952ceeb14317614b7a14a5313029aa4068b898f7e0f5b68683feff0d375f2ada37f20135df443bae913c7e96a29c6c3388b4b51432add89ee22826ad0b1b0a4ca9233e691f71a5ae2c76b5e5a135dc793e081dc53781faa4f844928db94084b53b39f1820c8342b563e3f46b002bc52ced63e4588388e69c9e85e2002438a1a703de411717d24ea88adef3051b27def61e4b9a31548d3714c3bee39fed866254033a123429043d0c08a052d2999a171b010ffd119f90bf9222462508ac914e0a68daf93f63caaa0c4302c9b1f6447ac3856b09eb45096b3a294731f110b90826b0d611e6e045397b07e5aa64afd271f1c92664e648af648642f786c0c8aae"
	 "6218f4282d8efa713dce232fb24df4073a0e04edc86d940e8ad22db8ca751143743f9f12585bd788551cc7b70821b5c42b133cb7781f60d1b9c345e9adb122ae444be456b8e49f9bab0e2033019b52f2ede4e7f56cc1d1dc3a48bf0666cc7a4dc6b4ffd5077673f2f6761688e4452a4c11b82598cc0ef57213f6c7c12ecc67164ae501b3e87e25a361d0615e48cde249f0193f2aa69a1eccf029340531becdee8eefbddca18905451b48c1085d4cb965786d3892d7144841300b8d2722e92af50fb828cdd8e825dbfb16328f7cf792f311f84078d45306fa570661e1ef2b34d5d36de2fc4b295f5e84fae8d55ca22bc15764932d0c5dd3cfd914b2b8f67477b2b5139c822ee2c511a03f7e9c717a5e8eca6c4b54f9c3b7d85765a78f03b29fb979811ff0c655522b341bb54ae3bc412eb760eb689c6b4c3bfb85a8ce794946214c574105e577acc01d3f8885e72db52075d05a75260a6e4a54872d087040ff38f8942cf150c3615088588cc53fed11040bed573c0e9ab14b987f9223ad089bb73284443f61ffdd61616b8a783e85618217e8bb491a31b7050421f4b0a0bfa5003775933db00e47e4452adc1433da2603f6dc5b9dfe58efe458da25699e512660ac6f1129dd9d7b176a24109c6e6e0c201d784addc9c7f8d4f309ef6fcfb02493abb7c836ba3a371e64fea941031a59adbcd4ef59f0dbf31f361f4282a0e60ced4d9d17675b0422faa1c2f932cb525ee07df7eb2643a67963aa99daf5b119884557ef1585d81eac5c8acf32438636a10d043bf"
	 "47093fb53a5b3ad544a38fbc3588bea3ed616167a79b2133efd8c509f53626b9cd7b71828fbd5d61b1df6ef3713b5347f65e7c0770715ac1fae561cc548864f9cfe281c6e5770f053f68ace64702c81c97976f471ad11c7551789ca21a4d5480c5d3528503f2f7fcb268c34498888d5fd3edf1c71d12581c393db2ff863e22c1f6c037106e5928aac9118702b45bd36782b2295782f93458dc120e79cb3d1632c2c5e527e56060b79a751cb7653b8c0ed2acc32168b56fe5b50ff9e49a71dc9b82f812b53e095660cd7d59c04f31ee47773a04eabccd7a4a6455ebc7d719c9eaedc4e6c935fc99642acd3e60e0f564efae90d7d1308d6ddfe7eb89520c234cafca6bc7e8ac96ed401bf96e3c9de704ad124b0f9381f22d9ce846fad0b14eeb5f93eb0e0fd0657c480fd2a1109d735f3825db598e2aa7e624f282673947c38aee8832ec8d4dc5d6a7306e3477ab4e37588788109a3ed76741f8f2a796d0f5bef8247eb298fb973c4e5d13666d87b0bf5a7a553f208050dd7140f64fcc27793ea82cf58fd86ddf805a700065888bbf6b5037815afe8c03eaea355c90bbbb448de13773e977fa4c6f06e7695e80882cdac40301b537fe254eb1ee437a6ccf3efa68899a7188e6829b58977917a9d6124cd2af7cfa567fb85aac9c6b971423681a0b6658575ea0dd32054800e08be5683faf46165c56647e1c346961608bdd8e6f999eb033caf73f000a71961cf2fa8c319f4084c0ab499caab87d13aca3f057d17748522f08b36c56c1746e49d731f9355100879"
	 "d7d114000293520c9ce71098d26b2114030615aeedabd5a6f7fb9a91f98b7ff00ec72c82136a00e5a19384084e0aebc78bb3cf05c3c1e3872f56e254c68694d930eeb46ca8e99329eb923ee0f1b5af0b7276e8600e25f18642247111eca41da427e5b9034a6a22627734ee024c2e2c4277edcb3a0309c3007c19416fa131086eccc6f73784e1a008dba5166e7c8aa4cf8efc3a4e14f59d665800982e46341b9b098508510c7dadde295a784f7a7085f5ddab5b6881b305f99d87ce3883e557280bf2a1f3adc69b7cc9d4f339623d21d569230e57a2bce611de7495d403adf451725d7ef11df4bde5a31a95bdda0d0c2a7869ddeedf2ca7e1986ef430ed44bff6ae6e44f740b2c65364477ade4dff6f4eacbffc67a2e0494c81e0424bc9220bf20aa795e2b20db6076667088b6863243ccd2bf897d4b6e1e58e2662cac593fb9a86220d65964e7f6e0f1987d07a4a8242c41c001ec38ed2442011d8a56919800b4d590338eb8db02833031ed0422bc08b11dd59b59f1d301e82154803076053464120217ca64bacc02465cdf629732cf709777452e177f4a4d1015fec4c36337ebdb8daf57f19bfeb247a27131ec5280038f3d1a766e071470ffb685cf4d9763b7e1b5776589874f3cbd4761d5fd35638918ad144a4a1bcedab9d652477951a716e4073cb36640fc257031f06e4d6f586a9a0b6172727933179e4cd433ba940571f3eb908535a12e9cc3ec1e8f8aa9975bc17241779d972a8fd8581dd3850905cec48061dd5fff1b295757e38ed8568c3a2967"
	 "ba271e00fb507b10bdd5ac5b90426e48e596ed430b5a3c554ca1cd0d18a90809d8db18853e2580cf2b2ca52ff686b7cf360799bf69c008f87191ee372b44f96696a12632af003eba51adf1e6101628168b92c718c6f7aecb765125880f180047ec3b89fa23bf57e4fabbce38ef0fcba829123f0a3ff527dad6d6b5b0c4b0c4c4cd13787e98c829bec08728acc5e90ddc6bcfe2254eb29ae8450ae87841a39958ab80a38c8a742de64a44e25df0360a9e8672148347d7812bdfcd9037723edbc5fb4a8bba689dfe3baf113778a498e2689e8cf1ad194df422838a618b0cb222aaf020705fcfe1475a8c205690379cbe2d0b5f9a0de41a4d2e6ff85f1f19a97712bdbf49bb90051ab934407bdda9bdbc1a57b0e874f3b2a09df45b7d01bda15330ccc57a752deb2751e495e394471f09f33d98d8face401d418affeeab86be36cd8cfb0f435d9939822041f256ad860733ccf137e582e1cfb5a8b96ffe646d1928657c05c67b8589a90fb32e078697fdf8a3ec58dc6d350a7f50c83d09e5884317829d8e850b7fe17bd2ba4d7fd94b86d060a3a97880fb350b95cde4542cb7d1a2f44f8ea065ae30fd4d4b5fb24f787b8462115b3a918155bae098f0fd7ae2d4646d3731d228909f690cf0116e1ac15899513957834e0a74d8c07f0c696cd3268d631ce1292f66b2633a3287a7e058781aef9d3d566e4e41395fa7e1793aa9f669aff116b99660a5a29fe127a0459eacc3fefa4be95a13499dc844d9faf72dca38d8032932084faca23e4022869f2034ace2de0"
	 "b286e71f2b569951214fd2eaa3d32da48a234265acec4967c74976b5b5d635eb12cff038a4a23d6c8e86a11a408aee5eedfa7209a8ce8d6bc10271e4b5627e16c5f8ce8000882c461de0113efd8ae9cec6ac4819ab2d6f8a9f189fa2929807fb20a895204edad9821d180c54e865548f9b3eafd8073a734e61d574923f0d1f69d266d970102434b0bab705465833ec9926b03798fa8a95ab98d35863b7490db07fa1abd600abcc3718d105f26f96d20e593ce0c82efc68ae65d03e4e2ed3faed27bc5799e359588fa884ac79c1ad4f5f8bcbc9a2a5605f97551710e2e416aacf149941265406490d32cc6bdde994943fac2102e57785dca3c20358cd431cee285768d9eed6ed32a9919e13f1a38304db6a57f637b6a5c8adf4e829baa82ce674ec7444fd9f7f1807b8f65d4b68ef7b6c3fe5bf653e81525f7900916f5d5809a52c070256e6b4cb332fced5e460c9a2f62bd73392bdf4522be7c211577559f59f62869e0a71f832ff493fab76bbe70f3c0b902fdf45cf49793afdb87558f1a6ec289018035d861990eca1dbfc412492cf86503af00c7db7a0a2c6374eed42b440293938a36f61e1c4c187cd50d974f2a0989b05b8ee207398560b516aea520044e37229fe0efa8b7038441fd584d79c010c0f31030d60eaa4dc1fbdb5a254c089198bb5eba6fe20655808c1d22b9604af1247e2b820823b3c622be2b01ca5f16f86af880908ace8765520c813afefef18e2c112a72fcd4760da91f7d1066cb5c8c902745b83be8defa193bc8b6b93a82efdf17"
	 "13a223660c6ff4dbbbaccb1a4e5482cc238388448e8b9c24c9aa3acac9467e1f6d96d6deb1cbc9fbbf77b7e756068e22bc3b9e6c275987c5eb99da6a5e2d90a1e0558c4f9fc392371c07a7844cb947b19dd1a6d9c1ebb6496f36bdce2967bea2971cc1c6330b1c31054c07f8d853858a46ae9370ff1d6ab755beb120a61b4774fba521baec6fe8a079862a0471cdc5080c0f073f7e3d33f0f25978d098f61bcb4905c776ce6c0562dfe08d8b9f17de4bc2048d962ad7f4baf132cd0152a904fea9530e7c1f52a85c0188d6ca38ff9b692b2a68204a6dfbfbec06f2d800b4444503bf2dde736be4108845c5a28909cdb42391b5a0207c157003b8dbd4e43996ab5017c5f21cf0d4d9b3145c0cb70fefa767b4689cb750fa7657c4a788b7759f86496998fd4b99b2ad1b2918bf330c1a81e8986eab031e9f86cd93b7d623c72e1a394f0862a193f21eeb858524477c3192fdf5b61ce9dd5b0bf3b3d7adbfa828f1a9ecd4dabf5e318fc40262f0dd204f28b934d1af7b0d7cbcc20be21f1c7e04fdf76104767892404b14965bf8d53003ca9ff0a8f15f5d9b2e152a662ddd8eaf7902854d8561ff088fe2e880a18a036d06c29997dddbfaba32ae4ed70b47413c2a037122d830d55bfde89ba645562cfa1d29f428da108d93562bd291748a728d1b3090b8a7f56293a3135f05d6876021e92aeede437dc7ab610e1e5af0a00c880887754d76b42b059f32f9159d25ffc56a993661d06a7973d190fd10c4ac998c8627b494444389c529e41982726f47135212b67"
	 "8b69ff36ad29e225856ad2081bd393249f469648e6ea4445e0011adfe320b4eb5cff1d9332c1779edae5d5d66931015e793f730be8482b5f488ca6372edfc71abc4b8aeaecf8051bbcc848d736eb0aa0d7ee4cdb9eaddfdcd4200c3e2f58a97a162565409abc44b8e982fb883b619fa80c7c4f2318954767ea1c63c70124f4342118f2c798adaa7ab5f6ebed1b0a15e12f40978ca8e5f0972a47cf397746f9f482902abdda10ee7f4c610935070f888b5ef8eeb07933e1d6ecaba243fb475b4c788cf8b453638ac43b9f6eb74654835678b47d9437a14300a12553fdb10daff3690e0802dab80fbffc401422a465e10e6414975358249d68e4ad5a1f1c93e295bc10b8c5c11ed98c7ca5773014a2739c0592dfa30d8756be1f66e4fcc01beb2dd58d87800e71d136c12b8f73298cd37b1bb5758376b2111921fa9f7040e69d3620415ace96ebf29fc1a87e392a9e701f4075208a1a8fda7a59b28997c017da70c18d2bbb5c91db86d701cae85a5742842fafec723be9d93b4225619c7188f5bd23c900ef3863068785363ab861b58aab8e91b562b26f72a812e7892ca0bb6ed91086a2935ba82938b367b34f70cbe40c02a8cea92a78588f90cddcabd2738c9a18450f6d3a87c7f827a1773c2c7629452f64e1528258a8ba75bc53245c705246963369f1179a765bed41d*0", "654321"},
	{"$dmg$2*20*0e2a3f19e5f9a89ef8371580fc08738b0dd02ee9*32*57b5e138dcba821a000000000000000000000000000000000000000000000000*48*4a33cb05d5fc441fe39477724556bf2a3445d2826dab91031374075f9b5cda25084769a7af11b2e678d79514be8e5f63*2726*8192*585b8129cddff9f9f5875d62364faf4dccb0625867ebf2cf7ebe08913e340c8bc5b62e4c4152b2274a19c3fb7d0f6ee32e7b6c502073785bbc213c28890b9910c878702b2e16ea0c0b0ed1462b831b1eb02a0a5ef586de3e1bb7b5f70b64e713f2bfe7f401ccf0a4430981b89d23afd47d05d1d28d64917ad2895af8264350f306b7a0b67029f6da75fc60137b99131d3678cb8c596295bef4eee92110d09c52cb30486709fff75b80753378918af4db98e69905245ec52c2c6ce7e71ea62b6e530269af23836fb40cbe12a1498d3d4e66ac26b04c31d4a1cc169909f51c0468edd44d051d79c361f547d7f4891195b96950ebff98f70b36106772abb775308cd6d42fae3a60d748330dadf7ca90bd474d05cdc678a0cf41a5f4461285ce0ef0a6df3a400d0116d1d1f17cd10be2c8f164ffbc3797dc022ffe52b69f0303526d3a17c113a56e67e54b4de121787dc62977af8bcde3f4fb596762ce31460a6f97d3d07874ad42f97ace146ada9b63f579a411fca985d85d64bd3262d1d2ab5721119b0cf8348abacf7aae2f57d3b667a5997d0fa448d3da4c51a6f59c6686a92a35ff4d6d951dc74acab9d956e9a942d9356291f56046c612ff09d1e10d8a0c60"
	 "bb2a4d273b03962f5399ff455ef480018dff09125f6c343f28b13acdbe7f0309e64406d2c453d57d6e78f10caf01d8dd274e0ca6e4a82a208750de92640ef97f67dddf90b0c6de767f185b6bf17a119a735cc97075b93fceeda807d0ec20bb4ed923ed8855202d7d285b767727bb5db55241cd21cd5a7353cc872f0d4a00fa0a50608eeb4cfbda71109a4a2ae97f2c01a40c4968c32ff2c01f05ee768b2ab22f12697805396916d8fbc1b06eeb320d619b0e472b763e7a72acd949e17620f69839543c3852c83e5c3b1cbdcfcfe0e3507a4fecfaf3f27118b6738ae8e33801cb1a2b4168f8f614dea5e673878964d6e27a1d8d8aede3bcf366400cd0155cf502cbc04234a2a418638531ef13c48917328d2bc1736e85be9cd80cf0d99b98d0baf9dd9bb3f840fd15d74788043be9f791540248b5dea621487810371995e5fff578de770699ed8de1f5190cfcd5d47320594299af29efaf204e0a411670c6f4f60652422a7e25ded5fcf26c1d83f805938c1ae578bcab6ea5c679939e5fc6593248d6b8fd55c454d2c69e8c756982c01ff76b4911ab494d90df56d7743f4d8017423a045eb4215963317164bdbb473620e8a17507a9cf26749c6141ab7b94af974db92c875ecfc4ba4421a37da4454867ea3f7d8580185eed9ae3271050d039c25f7b72e18024f91edbf3e1bba71f697c8451302b1ba97c8463b3699754fabf472ac399bd3a783b51cc945051ba1b411ea8093278606efe2b34b3992033fb773fc42cef45fb0482992d5f867416faac3912b82"
	 "eaa852935b54c1c05d2b5be854fa75ee754235ff1e84a53564070de838fbea7704fc249a98c7fd8a4d4ffdc06d5fc0ca39071fc5be83b0e37591e14ee76379f4c5ac64b21f016517ac44a12161543c43d40a8f92237c99de44ec220fdb502d82e96f01f020eef2752279a5aa3d3928a4cb594c5e145d016375e3d7a89d2bf12d4daf3886393c31615fef9e4201cc0208821e932e8b26df396e7c29f2c0b74c9f59ab79fa44b4f9c1156741e3da93df51bb23b756657187f1902f3d5c79aed88190b4a5f814ee1010b2fe82a3edd867457dbbf0598566d80261f83db810d058e785261635cfd1260c6b3b43081deedbf0b2a30d801618090d07340a6ad528b73c7d652efdc48fed161b0a0529d5d1e80fb0a63411d53e75e9ea9873d25a3bcb243faa406293f53a21b37e80023a302682943a30c8f1a5804a3700fb92092677602c39235246f359503cb79d2e084cccd2b40840acc7ac7b18b4e1a665e3833f5b4aefb40f0b36b70dd6b125ac9999d113fed15e5cdcb6ea6043036df3dec7f5638379971758e50f1453af5e48ecddf1d46e575cd2cde1b2091c1797df41f152fa77621f69169d42398312155caa88850800f9a8792c364021463467248e385bf45cd40c7869efcd6e9a24152bcfc8370ae901c7757a19627573a8832e5ea62c344fcd60230a3915561b6fd957750af61ced54ca1ff1a8edfe5ebbad51a79777ebd4e66c63a248687220e66d923c746f56f009f9d3f1f186d987c057af87f7a70a213c9c6eb93867983c3191ee956c8991275c5"
	 "5b07b2ef0eccb8b0287414a154afaca67f218ca43924fffe6e6161690756e3d6a19a29ca972987f603727397e5f4fa19d0c3f1e74f026d35c028bb81450c7b5493a7d837e83504ae7369a49b2354c6c6219c79ad8cf9f5bda3765541d9691b84d19cf1fb9534f859b58257e80a7548c12ca2c0fa34b8b6248b30213be0eb60de5bd04621c163e4ab00d80adec931ee00288fb98e5eaa8f6ec83af863b8a3634f955b54aff779725479d80f2fa51d25e721b159a3dd814db70836a32b3a4e55c4def271a1918805f31fd3af464c01006560b36e1ce0a745d3bb121710083101d1ee469b971400d49483b6c4d858cee24614786f227f320fe6105d61fa8cf21136e9160770167e1b7451a3d9171f56bc436f097d73dd4c21c245efd72b63fe21d1600213ab4f2250e6c5a16cfd3823de93c9c56ced668faddb77d60f4d4d9a9a3b3cb9de0eb5694410fb760b7421cbf6e40ca4e8bfd4577fc3528e0162ea4c9aef069b3e4f199120a10209a6acb1eb6e39fbb23896860eb1366c6eef023c2bd63edcf73aac6094d25cf3c1cb0caf82b1010503fc8e09bc537e8e690f8bbc0ef492f848f77442cbf28bdb42aa8932109ccefbd2ad6563fd3d315cb79a0a5f04772105e8564e01c1e22f1c2ab98813979da0a08ee8812acc1c18097b8f1fd95424ec0d1b63a85e84257d382400c5f44f570382ae8128fc0935a5f7f518ae3808b79ae7aed4990edd9257ccc74dd19adcde363d4c7e5a4594e3d3ce88d308cbb48fe26edad968cd54cb715e460c7b421f6debe9c70"
	 "3bd684a52b6b9571a7cde4568d7656e9bbfc5559d2c60e11054cba9eb54120bdf13c4c5103fc777033014404d6b4a65ea0a716f76a1433ecb904e9ac28b0bb8ab5c5b0216f62c18aa29b685cbe1c9172d51bdef81e7ead1ebb5d6c7cb078fd32cd63c72b163d2848de4c6dd59b35e853d6ec578b681af969941c16692c9010576f6f3777a24e87084c4b78a8502d083c137237a60705080aa90b2441e2f01ef9eef5b0f2b25b2b745136cb143405fe5c7ca013f88392428868bd9f06bbe41872c4cb1f98b16d74d064e66b0c435b52913b8153d47f52fd95ee73ab1f25f1533febb72e9dbf65d11a7568a17d2e8ea2616019297846551c6a3248b0a23e91ac1f38b21878a28f828e8aeb19893478aa2ff2f16833d1b69fbffe68b569afdd1980cdf6d8d4ff52d9e2708568db1a1b50847c8310e4d85dc73b59ee31a63bc894712f2d2214973c2741f4db4f3ca9a337e1f6c4ed3858370626b62e975a85e94b498f8c3c2073e6d6fbedb40e8a356e6d6c77c2b5e13ee52fafab4c8d369ce17a5c40deb98c98b60f433889e092d7da5e7e991b73c15127364d70a879b16ae774d65834fd0029c3a1239143b6398bb19ecda0328f39f39ade7a090b2c5c4e75e4922c50f858195c7fad64e4305d04dea5b85d4dd5a52ac4e60681c2337d3a2eb0b47745563f69352e1c17b08a3625f7ba530dc5a393238b6a2b92bebe6b94966537763ef66179b5c622ac068acfaf796ed4f4214d7fbb36eba5c9216cd5ee1d42132c459042063c71a1323eaacca0a94dc119145"
	 "cef90f744d16226d7168dc9abf46551dbe25ce179e85bd44cf15374ee498f3f3f8fb5800c6cbfc427a834e3f7b3b6b6c7333c5ed46eb2a0c93e4eaaa6f95072221d7cc27d36ad53fd5fee1e65d91e37957a9d34901602d5f49799db3cb4e47e2c5bcfe36008ff0fbf166d9e541504aeed187251b80cc72804687f58b646ca3893e8c9e4340c9580a2008d268e07f7a0705bf062c6b1ebb3a62a4c961ad2f65ec9d44c67ad3a39117d2427d9c3d067df7c089bbc905b319b30d61d099265de1ff42a97540bd08a1ec79a4cef4f692bbe54ca6f95d6ecb82d3ad2316d6cfaf9a66a8b5e5f00847b55509cdd344ccc3fc640da87be6cd4ad8ab3e510b31831d3151b2aea6675c97767076360bcfe1b317c3786dca2e4b3e90818064abb319cca7bae051390063bc6a0a0a133187a60a6eb82162a5061fba5fe17f157e9e589ad83d2f1760f4055879445b0934c954622476c29c9c577c053c723786c8d25829db7a896c66eec594a6b798ed278a824550795b0904e154fc06ce8783a773a8919b624dab70f92000b832475b77db27d0b5bbc5578765adaeac6f61166094fe11603f37a41fa047156f2e57d80a47d110901d96e33b5247a587552e37b7a0712cec420a5680ee8e5550ce5d0996b235b8898d67126415184bc9a0ec172d9f78f595182400c010d905fa73b5a6fef2f722b7f9dc51b9d21d85ec554c9f32612fcdd89577c47b3cb5203132e76ed5a39af7e9cfa2c92369464e14f8333fc29fe7a662b9373011f0d4627c9ba7b0ab0c050d0e67c625c"
	 "dc83a0e244dcfc7f5b58ceb0d1ca2f16349ad8b16a48dbbd63da41eb5d0732a13ce5a7ee7c9088739eec6d63e0a410fb53f83cc75915c0b6353a75fd2d219986ee35bd3991161fd054f0d39c2c9da696ec2968e801cfe726cd512ddcb6cc28af65b1f8e542d1ad6a6d76dd1582dda6af4f6c9363ad7117e0ea0102cffc1ba0d94dd8abdb5ac37ef9b444387bfac2b811479086e550ce3452f77461febec72ce35d06ec70b94779b794dab1a3fba727f364bd0a65e7255da20d77ac6b85ffee926a1c3c635366a4d5c8233b798e565752103c66d5e7f18f315f7fe2641dec5944e51e373f19fbe1b34dd00f4604a4f741a5d4a8c720bf4e51511fb3316951ea63c3129c4f6242a9014a78a050e633ea5bf85960fe340c54043d9bffb969f8abe458a8c9dd02e9416e0f3504a5bdbf6cd0b4013b4b548bbe59a23149a24296e0c326d69affa61a878baff7525bea12a4bacaee6c216de31e22e218a3bffc996eb7a3b8570caa06193b56452ab7f3430c758c3b447db98c7a1faeafffa497d938d9b952e3ab3f6774333a02742375e7e1dc39cee15313d69e8cad1a251274ecf48f273cb79c58aac657adc8d77f7cd1755ad9a2fd43b69cad9d2f8bd77695dac3c43d2469e4ab34e26c7debaf33eb2ca6cb7fd0a963a37b7dfd5304b9d5f0bc1ae0940bb40375001e9920d4956f4011f4f1263c3b7cb38afa1d8f7c8c188bd226ac3e23867f3989d76a402a9476756e03c6c3bc4e3ce78095125ee11e7b47347bab7a638b0088a3b18f23abae9ab2f94650a30e2"
	 "9abdbba8ae9d9d03cf5b12ab23f5a6464547bb7078b91f533ea06541941483359a8562e709608e0c5d1da2c7206c5af49be0df87a3244903293bbcc121fd2e20ff909a90ed836f1822ee2b40530084f02bd9c42b350a4703851d197d9c465485112f1bbb21aff46daef510159a1f354e5fb7b11508a3ffe12577b40d3bc16631f8a79191745fe828303cbe5b6d9578cd80f736971e1f108f02039e0bbcc12b42e8860cea15cc18505c3e4242ef481930f3e2c4b64ccedb5b4d9837461efc7c48f8b1a6dae1041e696b99fd8c9108ac1fa9d975b4d5a740c4e5bab92004b7c91cb64e80a67aff2596c919b73d88943538e0996a775b88857187e9f97828f8661f89252cd0c5577b27151b5b0021f17937a9abbfd8ac3946fec79a4063af00802d54eb08461f951cdbcec92f593eeba457f381a7a98f313ba28d21d2574fc751449e1c3b497e09b90f8e1840e7a56159915d98b36647dcc15e1b335102074741f1dba46f0df9e7114ca29d02a7e4581fc45c48e6b31cb291760a05774fdfdc0448abe313ca496bd2d1f011f4706072d69eb0207b0289f5dbe4d1f73355b206ab3d5c777d1d9dd65281a0dcdf598569109e8fc3b56af94e4340929457d2c45d9a9bbc37741dc031136a11955a465e0baea8c11c06ae9321dedadc498570efc3191e67354f0cae6a763e84aaf74597dc1d329c81231546df2fd965d2ce0fa2026e0ca896d48bf8cff97e9e1fc5e035a13a1dce07810a9e87c21988d7e9bf19dd68379f346d232f83d776c36791ed1ede88f8bdc1b"
	 "62e3e7857fddb802ef7771be6a2428b7bb7e419cd95042d7de60359365efec7397b4d7fd32a4d7e8b924930606e7adc49333809812635939f79a20eae6066fc494ad27aa5be989663ed12f9f1c82d092b7a4af546f6dd33ab862fe21cc45c2c7c58842360070e206ac341c26ef2f92cc7629d873a219ea1177ac6354e7192f4c3f3aedb580c322e1644c92b9882a96addd01a35371c07b6cd3d7e4e38d089559ee41bdaeaf81650dc263a69fffa6d2713d3a8ffcadde7601cd2a87c23187463d3f3305a36ea01743d2cd846cc5ac96c89241c86b3c38ab97f1ab7b9685e68260fc116b7d02db8cff929b871dc02379d203aea4160c6302a7bad3379ce2b77effb3f9eb37d7826181ac8f606e67026fac0f43e39c72a04a6278f89d16a6c14c6d6e3dab80e9089a83c7a370726fffd0a2e6a9a6a950fad60982eb28b638ebf2315932911b91e465f076e97aacad4c6e19ec46a8ba9e7a19fca03b7796cd6d8efe6d2fbbb96b3fd3f85d4622fef029819efb34abc28143faf10ba4879fa69d493908649f03853ea84bf7d5bb21c6c541edf0c0aa96347b4102cde3c27a58ba0788ac02cdba243a3f52e0ce4d682d41d432e632635cdce5be1542b6b6a8708e144a6acf80ab3ff5842ca2db90e9d75401cfc99746a0919ed81983d2171b4093b1b07e5e5c45992f657c892e91c16cc6017a66af6466ade21f4b378a6fea6a8e4bf000ee986bbc0a170467548e7f6e797381ee89fc431f7aa562110555dfa5c275523c202744541d51701d70a8f3006ddbdfa5f72"
	 "9563bc0234d0b2759efb747633221706cfe73d47743ce6e6077943ef6d0801729e1301ff9bbf37f50667909f1cdc70f95040c841106ce566de5dded0fa485ea539978a88ca8618e566e9da4f2e215d544ee62accbe75dc17ea26962d78bcad516e6bff3152642e346444db494a909478bf6d80aec53f3ffb3311c6283711eb96fdbdd8e6d94c71cbfb9d7ddc7f092df5092199dfd822b98e21239bb8dd17f0c101909bd38d309bb5456232f5a1b731990a4cce847394fc40b859a8d89c7c02c388e7d6ad42bcf4818de33d696ed6d6ace4c23d51fc9d7d82d0602dbea094aa2db51d9aa8ef5c1f4803e40f6f5fae44da3c3c6ce9b1003d95300871353762062d1ad49a31cae73d569bf07d147a0c8d212e60b1be486df08bc353a2e3ca7337b83e3db43be03147114c229fd32fc2eea5f64d5d5d9848709ad7335dab3909c1232d93e76eac218e7e0497ad5b7b1ca8d9ad5447879b20dd370398eb8ce4bc6805064ccdaa6d8ed1e98e259b7654a75848705dbf2c3804b455a9e3dd2890f8d74f0e968dd050ee81af2f98fdfbe831c16dae6589b9b2a16965713b8fa52e5d2d4df504411ad9c14929e560a5f7e74e98d72f71223a5eee41a40d85c177183c510881950bebd3f0ac907fbc5a4efe70a60da6bdfb6870d7fcefe04fdfffd1492c5033ec79b8de002c41895ea6e84393db391b9692983c84148928ba0fae6b2ee3aed2289a9e053d47340b5faa4870fa632c1b81c516a58a049728f941f57bc34ad53c236d33dc2ab6a196e896968d0a2bf651889"
	 "825b8f358ef4874b0e75e39331e513c506b29a61495e78722bb25475ec2ddcda0816ff634062a54721c9fb425ff286336e7036928cfac29216dd0eacd3e5328b6979f831dccf403e87ccfc4346f5743d972d5047f6055bd86c98b8fb720a3cc3f459750ddb870a845c1ff4bc3499b1c92b6e591eca7e94f1f8d2fa3c57fc97b573a738f7f55e3b6cc975a813ffb7f897930b8de8382c5883ebffba463ce72b0c50c721db403cef01d5be035730ac3c6f6a3f78681218656f397966753c04507e08a09f7176c3e37de40b9c7faaef1b675fd083c9cced4261dbd4a289f6aa0ba04964e1a6d328ef05786933d67d6da009aaac7d4a8ca31df5a15e3874eb9b288edf7d794e1abdf9e411c5bb87f7fb27f76bd62968bba4d53844e76487818ddd38620854debdced8930ead6b46f3bce6009683d3ffedfff0be83cd8727bbcbf428c761b79a3c06a7c2de7b99394030b51eeb954cfa3fa307a37881a8dcbcedf9549e2600b72f3665946d14071d9d22894020346466bfd2062e092f21e38e920609df77e3b8ec024334c9708a415d3408e22645f06cd6d805e8da2f4005000aed542aa995816bbbf32597d9025daea32fd07733e080188d6c5c7af4ce8b7bb25d7c""50e9f3cec80e86a8f9f6d4e78a40ee20fc3c83bbbd07020f0092cdac8ffc2d52c24166d78da8ec32ebc49f815264c5ab29ab84f3b44ba75c06b80aba2966a617830efb08fd3fdda831fedeb67b7d593c661538d422e1a9fe378acf51b0f2a07f34d84624e0b90af172e5976a237a7dea10f"
	 "a7cbfd3203d1b4985a1af6c2d2300136226b2edf519fdd2b7b5e3fb5b0c70f2e3160305fe9dd0c09b98d522666e5100532f516bfe24d12d46b5decb4d4cbdd5fe9cd647006c1c7eba14a56262fa7a3b7b6d7b22032c1d444fe023d66b7f51004c6176f4c198a2998beab66ca70e1343187ae697e9fbfa6ca6443d617552e6b7bb73c59613ce0a7cab58545bb40636f54ccdf89c507098680f4486f821b2fb2c7baa182686b0b6f893fc9575df701196b14255b547b925387cacd5f4a762b1d4b7f713e7aebe4f75ed648b8666e60a4f8d92f752451d704e19aa102bb3dda418c80f3b4f395965ec36fd9474088ac213b38220df73c8159401ff87751bbe392e0aab031de59691a0a77ba2ab7cfbf4daf09fa4d7d61dc5b456dfdbf7a60eab671ed1f1a67fd58bceb34e981a2dc3c3bb8a7a14fc8443b47a123662d96b4df2c584856ba257f39749d51caa70b147d50c68d4aafe51ee195f1ccb99b7015de726b5f0e85bf37617138d2b24d1cbe985d8d1cbb40a52e4c57e20c799e2f5ffc0557be9d3e2bc5b99dde628c4dffd5c8704c78689e967bc870c0fec80c3c69a2453b052a46e142309fb21bcbdad7c6c5a67df409bfb9899ec58ff0973e1813f47ec6428e35a932c117b5dc70a8f5b1a9fa402d59fa45714b4bd79bc214d488939f997add26d13c147aa4d4239d8aa0e3c70994eb4a8debb7cf292b3ff59bc36f97a9acad107fcc556c24a309c4a15dab16a47a71f31324dcc8183fdaabe1fbd1cb3808c1c35c311ea51188759d4e1533d39a9547f"
	 "04054e2ef994c97e213669f08db02702dd8b54154e7376f256dedc67fcd3dc48f5e0be91f1f88766415d203bb4bb11c4a0f6d0888e0c98d3b8519aab741b20ced0e02a5638e40ad2ffc301318a77e57787995acea46eb8ff7edb535036c3b3781d63a02bce56499cd03ae75ba6610ef27124da36dce85ad406c82e72a0319dcd6e05dbc66523be5015036de859af45be32c664c18ad712bf09d361769be3e568d5f51c943ec2c9f74077cb9f5757de92c643a2963d69c2cc3f010908e661f3a6ce202d50d72a436319bb2337ab1babd4f2cf1bffc3de25a09dfc5cffb31c7080c5473b4ff673fdae11e64cd492a784a106beb65bfc01f9b7b97384d877d9f4440b7434240e98656703edd66279f1bd5b7cfacc8a6b511f1db9060e813f2e37a8be5de25087b0520e7729a873e125d7cba84b93cdd333e8756630d9dc9e1815832c8dba1a3c51776948b184a916ae44694664192af75a616387f47319bcd5da1d94fce857c8e76c3438ae5c7c810310058558e01b01cfb5676f1a5a5d027bcd1ec62428a82b78fdc9dfe69ae9c0301f6f2dbf1475e1cd1804d05cb04583ae62efe63a6f1d20d5c5675f4822ddb8f6f6af3d639f56839b1993dc40223341c04d829849dea53aba7d0d2a2db0a89881a2ecee4f66698aef5ebdbb3c6d65ff03cc1a00b714112f0b111e7a97ded2abde97767e0ea6e19a04f96d708d419f457022ac21715ca86305b8d5e4f45d6382c7ce8d87a8f0f2f1a18134deb9a33b334bc04697479c4f438f5e58a62a1b22b49580fd46eb4"
	 "946d07c505e9c778dc56524880e8fb565487da236bb1340d92dbe21516f40a05dc3cec3fa4a56bc93ce57e7be50ef2fb38c94790acb9702dbf2ed30d6b5cc1e0173ed4c19e2822e79e711a523ecdeb6742d90353c904876e66b30fba8975d35418f0ef3fc8e5621d8d243973addf756d1e4621618fcae42af188a22f47f0f8bd0e821c16c8ca2a15e35d855ccc5c9660ebd2fe8966e6b86326905267b80358328483d0045fc63af4edda4020ecba5853f005b9058dbb81092cc12ebb3205ade902cef207f783a3921225f3a8a108eccf02cc303b11a2a7db60c897f31480db900fb1a6e1ccd1ba0aa61214037e50d8eb1ac777fc4a467ff9b9ffcaf34fe721300067d33a25f9acd43888ba09cbd26e8b269fe84065b5c44fdf734545fe21689b838eec4a00860f654df33f87d0f115a6fc1ba4f0de641f06eb8a19d2e75aad7dddc6f00c8d598015541fc8bd22540b9bd3babbbf3e41212d35cfef1236edfa5746b733de738c60901b87bfc3a4c7d49eb16e7fbb7ab93083cab5c225f79ef03db6d490169b5ecd2791fef9045e017f9dac41dbaf841f050729c6adf789b8008a82e61c80cc4d06207dbfd6b2a9cdfb67ac26280fa9ecc298dac1878fac6188066b9d8637f772136edaa7f64fa491b0bb4775656f5f1a3135686205b8217a590c088cf448892e134a29ef4cc61bd76886663afb18ad504b204ea52ef61782ce9ba44fbf2e18e1d59302a1b69717375be70a295517b069d26e161c91ec3a1a782e38efa6ac867dbe488cfddcf8c200135b059a0"
	 "da4b4dbadda9b742b906266a879da79da144eba455fa7cc5062d326996acdddec0eba8666b0e1e6c7116a1e5f04f1e94e5d85b77b2d35deb45402a589d46734810ba3a74414eb53181f75c2f0bad61d9f4aaeb94f30a1051f5ba2b2b30f1445bfe889da81e550449d863cd5af77d49d344b63666df8206bc04686ebdaee954da5f14692bc2bf1b4b01cd6b2bfad93dcc7e5c08a5059d047f6ffe96a17c828244b234a2abf28674b15d14b735956c0a9bd438183666d6926912358edea95ac5b1b6a53784f47819a3cfd4ddb9af8e74f30e06c30e218edda9eb8207dc7cd931d6e926af59f8238225dd037b47c7a4c8af558d981a7c9a7dbae3fb66345874b27cb229f1c82b841cac0cad018e8f75d0731d5a8ea0c4d530f575de7d39d77fffde64c9d1fd87b9af3759d8a275d5a1d95f1d2d0bee007544f5c39ecf4013c80cd89821f79af3979f23dfff87d093b85b892b93bec546c5eccabf41d04c65bb571543f2312ed5e3596ec5d6bf8e57e9854164d34b48ca0ca4044a526e038332348eb801a6ff342bf25750abbcfc27e7cb5e7b026db3743b210b91d1fb688c8f16d4e40203d39272f22b5bd0f796f0fa09c90*1*b48bda800b2b3665adca330cfc990283a604b08074521335437c0ed7f2a997069c88d620b638ee988edb3f6f32be1ccd01ffb14b66b2c213d31aad92b25f66f226f2793b5e554475ce8c1a7f9541ce66c594379303ce730fd77a6591c97f5bdc400ba7e8cbd496c188c2112208778ff9699674b117631d8f385ebe45ed91dd60a"
	 "4a657ca39c11c135e426c03ce2219392f55c635c1736f31b1a7a892273b6d9e2867864606aa0244b82c8be1748123f0b8478baa9402521583f24ac86c11801fe340e64628e8840aee6a093b1bf25aa05c74d1c1dd8ec48321b34a53bf78347a59fa9ee394a60b845cfd4c2f5bc53541065f1c5a0d3953d9808b26ee51d17dc026ea97a2ffae213bb9818f3c4009480ac0d1774e6237546204339db20ab366a805ba8c34304070959a16639006ced72bc3ba6430ef7e5a10e9a969ee233efc23b2d99bd8d49c3615f0da372cb98e077829f07e112a5bf4357a3cdee0268bbee69d31fea1ac66564d4b1c7c303f9b41e2b23b3c7825d1ef93ae1ca1aed1607177bf92cdce38fc68325a652efd3791e922a196eba24e9816c52afeb1d84577b8a22125c1d90beb57cacff4b2a637061d69bf7f1f006d102ca2acb8471909689d36196ec300691ddb9369868f3fd577e463d8b74c7a8e95fe2fd2954136f9650f7301d4a91d9c41f647675d37c1663d4b5c50cfb175facf30598a9be1ecc2f33fd4ec7e1ecc7dffbb1180a5b224b4eb6d0e0af4ecad6cbcb2a26cb3365a723caa2eacf9404083a427d5e7e62e967875e53a8eaf4f5873627717ce802b6b66d627f3390b50c0c950dac739ab46fad66920de3fb8edb0ad0a3c93e7b3beeb90a26a1553aecf4d1f3b17b7f852cf5441bd626012ca14d8e4aa2c43ef6a272f9f6990672b2ead99d839617069117aa10f840c379fc62de5ebf5c82ed59a5a1f76b0fec724ea809411709d88fd2f986c35edf9a562e3fd"
	 "bb13577e2ac78bb854768ab38850daf931c1b8cc3e6f3c244fb339d288348f88f792954e90b68d664b7f941b634aec4b2d54995ba08b999d32d007e85e7e0df4dc6022b0d6d7a23ac5bcbfb2dd6cdc300fd0e4c9b4403a53a67a1c8979774833ba4b8f338b1932424b8654e02ff039967bb43c3f0661bf22f638a4caef57d50acce63e472f1316fdb93e75218d630d958c1aef855a9a7bc54122a26ff94d78e74d48aff82a485f584b8acbea147666712d35a7167dc5f92ef4059e42c28ba66fbdccaafe71efc630b8ce7fd840bd2802c2d69a4b09a11cf17c9321d9ccfb1623bfaa89786df732b405e2cf118611e9ff153dd2db2df1953fdd888f023e74e23f3a5595b81456b6ffb33e91d65f08fc8eab545412b18be47d14ab77827073286a735187bed1b12fbed879969f7d06c53041a6bd79bf6c5260342480cdb50cb617c2b4111da501ea98f368320094c5353a36df520824ec52dd15e818bec43d80b537c0d809845645429ea4f7635528cb7b8149924053a76d3c05b0c31e5970eaa014708c64c902be5272513111a73e682ed9f473c87b964a4957934424bf957d1e86c6c90a967a8643eec2b65f08d4c91252cb9663a4e5aa4ad9180166ac633c0e5f5170656373489126e6be09e9e8bd6f226f0833bd392884dfce749d68ad51b1f0e0ef5fc5a8876e54558e191abcfc4632409547a8a5c46c2b546db07ba324b4d327ebe86f87dac27b64d6e0c8250019c1114a4f8fa39523dc3f5d597aa33af245ecca15ea8cbef7604eca5ed804ac4f57c12"
	 "6e335763925b88128b7289566270a5d7d1602481647f74d71bc1eafd0913851bcf07047dfef51b41fc02215d136885e647001f9f47546e9ea6ba0beab1d8a276cf9b85d780c05d4031f55d35d54c56f7fceeae9d62c58e7e928e591c2d6b1d14391f829f3e30bda6132bc513227cfad357be2c6f045bad7be72d01ceccd059327a72ce044edd534a5ddf71831bf07ebe84806feb621a5b8d71f4a608878e5e5daf3f8b4b3eda75f74f03d1ae5aebd029f037f66253f542aa06cd6c29ac5ed27ecdc7641fb6d54c98e71491772944303d3b6be683ac44b7bda5d49209133ff564cee31912b8e024cf628e0719522b11eff2e32874818f9a0ebde427657558a72943d6eb25c4b9d523336f37453af157035a3bc5ffd13847a928450d4e01f2ce7ca51d456939363c3e5a69b0d25311682c7b266cf86d12b63dcd322be77594c7f929a77467566a8d86a7d2b583b95f76626244738251fa762e0b2825c7668d6dde8ac5579c1a06318e5c5a6b2b1bc93bce6cd4853c50b6662482549290b15500722e3d6772c7541e3c864291dcbed84496dcc9ff4dddc974aa8b17b7ccea56c856f24ee2277a391c3c0c2c5584111ed24fe64e478e3c4d22380b8183222570fa3c70d29230aa21fd21808baacfd41e2430fed7c3316235e6b4c2c3331ee36d9e5c94ddbd73b351897cab7ede8a7c417c753d8023cf46694acbc9aa6ca556da7de108005330704cf54b1ec7bf7df02e36cd736237316b3523bca0a53a2472e68d30d95b1eb49282b27530bc69cd154b7a4dce75d"
	 "a3efc65c12ce45de7a63632d340fc61a1789129df1554813a15c9a6ad101c07363ba8d967b70ae1767f8927440678bab989dbe994922779c3c277055a35bf12d6909caba8a4b6bec7f49dd32426d858e53164c8db77bd1b9321b31e6c1ad1e92596bec4ad39d5b6944c7585a5ad0c6f83f64727a7f6397f784d865ba3b9c85343f3a2828a0e71d75f19036ea0f17e265750d6a01513be2bee0bd0a837996971b87305dafda12679bc118a1df188888396e10074254e4aeecb6801e00e8f3ade2889b65aba9e29d2d146001740116c893df1899175dbbf88ec175216df3d93a88fb6957adf64a3849e26194edb91188c0373fdf9be85a520c173817ccac3e4e9c88ce0bd9448be3f6cf3eb92b9337ecf2e63db5887e1113ee31529c373e83ec02012ddaa8812fa5c6b8be8febe29d0c286fe03832aee79018fdbaedd8bec03345c05faa1231ad148bf4531679738a537ec490bdcf78a0d9dd13e6988e360273c388b91006a66176c93caf3594cb098d5f4287a37d79b636eb566eaeb73ef76a4a480fad73caad3378d17a9395bf71c6c43f643b04b4f1773939329470e51053467b67ed8ac0807b8806d26d16f6f4fc15b3f3cc197d24ea26418cf970a5e7009bd871aff96be823fd80efe1adcaa882c168692b53bdb47effc666a1768d04d0d8bf199d36604e82b72fcce53e86d063c347aeecc79a846f8e12cdec679b857f85a75fe59a1338a411950459443b3fec6511dcc78d5bb6dc60accd6013400c0ef71f19d7713b37777a75e96d0d341d416c9cd94"
	 "7e3c442f6ddb31daec66bd96ca31b01d2dfb99d312a651ba5ec1765354de39d7aa4bb096ce7edbd93829d8ee2b7e3ff364f5d87f653a541f033db6c3266a03046f8612ad8d56a1c78912c9774c86a8d7e2eaa7f3bb1033470789ac2c32bd3c2ba1269bb01b176b167688f8fbe1f6094c3e2736bdc1cb1733364011681be98047cdad7d998241e121e6508cfd665c42b30f22bc442f940b5c7d93659f59abcb17aab1f28a02d0b59239f148211c525dd209cb932c54f24fa8a9541f0eab28b4c8df80845058e71e5447959bfc7f7d28e15542523410bc162f566875ed6d9d4fba519000b8c5d90f894f2bc74dc8307e26d4e0a9b418487d7470fbd64e97e660a3038a10a26a80e7cca09a3280ce3c87d07befd6f65127096d6075a18f30906828cee1f8b968dd3247210041078cf6d28f05977e5c172a9ecd83167873881e0ffcc56615ad0d64b0189ed8d559e43cccb1e2f8805df7156cb11f5df9dfbc067fce9fb3ee3230e28edfcf98741b9883f9f0f42913cc2be1036a0590107c69a9fadd4c9fc39df872f0db664ea7172fd72e0ad756be95417487d0c2bb38061c52124dcb2545f15a5bfd39d950b5878a067945733d8b1dc37cb85dd9393c98b0751c83d8e848fd1bd3ad243f6a8af7a8cb8cda7e1dc05324fa3932423fea0428131646534e74398f1604146da26a615045ee49ae2df3c8fcd16da64672845a946de4c26c1417c534a2b62a408a8c30c2e4f73ee44571259b628249c9e3f65e7b8d22002a170e7e53dc7c4cdc0073491db2cd6de20cd"
	 "df07501ff08378ac1cfe3ef479491f3fc475f8aa1fb188706c264e276da3e0399e2bc17cffd6ad0ff94d2d3b9a3b46e8c1472c41fc1c002daa76634f94b3bdf8560cb3241352c6f1be21fee70cd54a1d96e31d71ef99589b93e7ca8d026abcb4a4fbfc8c0f57d59a6d9e760f02fd0a569702da7f59da495c2dd7f92d60fb3220cd7932a032d40ed29deaa5fe971128c6503eb9d1029a23ed6dc4fd5e8c5cf0347841424d60a5a07a9781d08c85222cf7241d199609762488332a6eafbc08cec42c876da9bd3fa287bca12f71b6e33c4453afb970b425a45b9baa9aa69ebb3907e06e6610f100b00c86752b2c106c2e0b71963f1933d315ceef89132c7744149db0c28f62b3d7b43d570d1f5c40bf4b7470b3b8de30b0d756b8326542743f2fa5cf3eff226b6a658ecbe44dc9a0e59f073f999d8c3340ba30ecff6f2fa4f3815f0d4c665b5109ce8984971e5cbec806888c2acdf73d2a330de9e5133787aa4950d08759f4cfcb55ec8efb43d421cf3a9f601a096677eb95f61e352a9adae7c0b971fb455f170c7ed95329b699d6e93f024786507e2e0acbeffb452c26d8c041cb88316d09a08af54ec48451f9bb685a23910e97ac82bb41f19f6b42fa10cfb75f9fa8edd61653c14a27b51544e3fb28009aab76d060135df2d097fd4c2f2e63dba1192c648215fdd1dace4824d71e038e23184ede7f61baefd747aed93b9807d0b3b7b4f7cb9eb171d1ba241b19cf1c74781eaaaca99a458253777522dedcf3d1db6bd4eec4459e59ad635904201b5d91c77bb"
	 "b6e91f00f5a6f29794b35afde3dcd850f08ac5da097549ded05159567e9f7a023e08e49253766c0e151852714987201e90df675368ee638a947b7e6dc20bedf60656971170afe2d453662685dc1ceef8436ca8071680d0346239b41a6825839e9d5af12f9574d51b4672c5fa7f84bac497c8ba5fad2c10fbffe5ee713090b903d7723cd28c1b189a47c6a9fe9a88d0881dd60d1970c6e8a6d812bbd089c10841e5ced1417bef41f400118fa990d157bca93267d407989de017bd48f0231d43b9487526072e2755461274b3f5bf27847dda36c652a2b1fdd3815fd4ab93863426b31ecd1e6a9094dd2ed0190f8138e650dd2174fcc6b6ab1b8b91cc8020f2dcbb14855e7dd0bc1b5a01f55f81c0476daf1684cc4e72a68327120730ae92c45ab4e447c4ee900d61f79681667eec61343e4eebdd65c5b38a1ba5e3478f4d2f59d184ec39aca445a0f6edaa6840f04bfc19acf23db4507609cbdb44514b36aa5ef4ffe46577b711d1028970916eae919f1b4913d5894a24117cd7cc1aa8965840865554ce663af470455c0f756c795fb29eec04b727b12f7f3796f572ca2ec1e8771a88f68999e16b2acb235a7d9146f85f2be5a034babc3bdde750eb7895396d4777c144aee517a07310dcc8c9ce0ead93abb7f1eb4e34ed5036361d682c97eac1ad7c8158035e40a713f0f2e6f6e677d4b11ecc97e101a5b48420435dd218846ae622b416faeba7e0003bbbece71c2aa046715173b408c8ab2888b0b5dc4c34683f83ba9a83795f86122e6d80597d3a952a44f"
	 "5a1edb6f294a0ceebefc3cb54db814cf91fe450ed4c71d0b4091a1fc7474", "goodjob"},
	{NULL}
};

static void init(struct fmt_main *self)
{

#if defined (_OPENMP)
	omp_t = omp_get_max_threads();
	self->params.min_keys_per_crypt *= omp_t;
	omp_t *= OMP_SCALE;
	self->params.max_keys_per_crypt *= omp_t;
#endif
	saved_key = mem_calloc_align(sizeof(*saved_key),
			self->params.max_keys_per_crypt, MEM_ALIGN_WORD);
	cracked = mem_calloc_align(sizeof(*cracked),
			self->params.max_keys_per_crypt, MEM_ALIGN_WORD);
	cracked_count = self->params.max_keys_per_crypt;
}

static void done(void)
{
	MEM_FREE(cracked);
	MEM_FREE(saved_key);
}

static int valid(char *ciphertext, struct fmt_main *self)
{
	char *ctcopy, *keeptr;
	char *p;
	int headerver;
	int res, extra;

	if (strncmp(ciphertext, FORMAT_TAG, FORMAT_TAG_LEN) != 0)
		return 0;
	ctcopy = strdup(ciphertext);
	keeptr = ctcopy;
	ctcopy += FORMAT_TAG_LEN;	/* skip over "$dmg$" marker */
	if ((p = strtokm(ctcopy, "*")) == NULL)
		goto err;
	headerver = atoi(p);
	if (headerver == 2) {
		if ((p = strtokm(NULL, "*")) == NULL)	/* salt len */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		if (res > 20)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* salt */
			goto err;
		if (hexlenl(p, &extra) / 2 != res || extra)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* ivlen */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		if (atoi(p) > 32)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* iv */
			goto err;
		if (hexlenl(p, &extra) / 2 != res || extra)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* encrypted_keyblob_size */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		if (res > 128)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* encrypted keyblob */
			goto err;
		if (hexlenl(p, &extra) / 2 != res || extra)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* chunk number */
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* data_size */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		if ((p = strtokm(NULL, "*")) == NULL)	/* chunk */
			goto err;
		if (hexlenl(p, &extra) / 2 != res || extra)
			goto err;
		if (res > 8192)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* scp */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		/* FIXME: which values are allowed here? */
		if (res == 1) {
			if ((p = strtokm(NULL, "*")) == NULL)	/* zchunk */
				goto err;
			if (strlen(p) != 4096 * 2)
				goto err;
		}
	}
	else if (headerver == 1) {
		if ((p = strtokm(NULL, "*")) == NULL)	/* salt len */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		if (res > 20)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* salt */
			goto err;
		if (hexlenl(p, &extra) / 2 != res || extra)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* len_wrapped_aes_key */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		if (res > 296)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* wrapped_aes_key  */
			goto err;
		if (hexlenl(p, &extra) / 2 != res || extra)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* len_hmac_sha1_key */
			goto err;
		if(!isdec(p))
			goto err;
		res = atoi(p);
		if (res > 300)
			goto err;
		if ((p = strtokm(NULL, "*")) == NULL)	/* hmac_sha1_key */
			goto err;
		if (strlen(p) / 2 != res)
			goto err;
	}
	else
		goto err;
	MEM_FREE(keeptr);
	return 1;

err:
	MEM_FREE(keeptr);
	return 0;
}

static void *get_salt(char *ciphertext)
{
	char *ctcopy = strdup(ciphertext);
	char *keeptr = ctcopy;
	int i;
	char *p;
	static struct custom_salt cs;

	memset(&cs, 0, sizeof(cs));
	ctcopy += FORMAT_TAG_LEN;
	p = strtokm(ctcopy, "*");
	cs.headerver = atoi(p);
	if (cs.headerver == 2) {
		p = strtokm(NULL, "*");
		cs.saltlen = atoi(p);
		p = strtokm(NULL, "*");
		for (i = 0; i < cs.saltlen; i++)
			cs.salt[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
				+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		p = strtokm(NULL, "*");
		cs.ivlen = atoi(p);
		p = strtokm(NULL, "*");
		for (i = 0; i < cs.ivlen; i++)
			cs.iv[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
				+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		p = strtokm(NULL, "*");
		cs.encrypted_keyblob_size = atoi(p);
		p = strtokm(NULL, "*");
		for (i = 0; i < cs.encrypted_keyblob_size; i++)
			cs.encrypted_keyblob[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
				+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		p = strtokm(NULL, "*");
		cs.cno = atoi(p);
		p = strtokm(NULL, "*");
		cs.data_size = atoi(p);
		p = strtokm(NULL, "*");
		for (i = 0; i < cs.data_size; i++)
			cs.chunk[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
				+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		p = strtokm(NULL, "*");
		cs.scp = atoi(p);
		if (cs.scp == 1) {
			p = strtokm(NULL, "*");
			for (i = 0; i < 4096; i++)
				cs.zchunk[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
					+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		}
		if ((p = strtokm(NULL, "*")))
			cs.iterations = atoi(p);
		else
			cs.iterations = 1000;
	}
	else {
		p = strtokm(NULL, "*");
		cs.saltlen = atoi(p);
		p = strtokm(NULL, "*");
		for (i = 0; i < cs.saltlen; i++)
			cs.salt[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
				+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		p = strtokm(NULL, "*");
		cs.len_wrapped_aes_key = atoi(p);
		p = strtokm(NULL, "*");
		for (i = 0; i < cs.len_wrapped_aes_key; i++)
			cs.wrapped_aes_key[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
				+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		p = strtokm(NULL, "*");
		cs.len_hmac_sha1_key = atoi(p);
		p = strtokm(NULL, "*");
		for (i = 0; i < cs.len_hmac_sha1_key; i++)
			cs.wrapped_hmac_sha1_key[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
				+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
		if ((p = strtokm(NULL, "*")))
			cs.iterations = atoi(p);
		else
			cs.iterations = 1000;
	}
	if (cs.iterations == 0)
		cs.iterations = 1000;
	MEM_FREE(keeptr);
	return (void *)&cs;
}

static int apple_des3_ede_unwrap_key1(const unsigned char *wrapped_key, const int wrapped_key_len, const unsigned char *decryptKey)
{
	DES_key_schedule ks1, ks2, ks3;
	unsigned char TEMP1[sizeof(cur_salt->wrapped_hmac_sha1_key)];
	unsigned char TEMP2[sizeof(cur_salt->wrapped_hmac_sha1_key)];
	unsigned char IV[8] = { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
	int outlen, i;

	DES_set_key((DES_cblock*)(decryptKey +  0), &ks1);
	DES_set_key((DES_cblock*)(decryptKey +  8), &ks2);
	DES_set_key((DES_cblock*)(decryptKey + 16), &ks3);
	DES_ede3_cbc_encrypt(wrapped_key, TEMP1, wrapped_key_len, &ks1, &ks2, &ks3,
	                     (DES_cblock*)IV, DES_DECRYPT);

	outlen = check_pkcs_pad(TEMP1, wrapped_key_len, 8);
	if (outlen < 0)
		return 0;

	for (i = 0; i < outlen; i++)
		TEMP2[i] = TEMP1[outlen - i - 1];

	outlen -= 8;
	DES_ede3_cbc_encrypt(TEMP2 + 8, TEMP1, outlen, &ks1, &ks2, &ks3,
	                     (DES_cblock*)TEMP2, DES_DECRYPT);

	outlen = check_pkcs_pad(TEMP1, outlen, 8);
	if (outlen < 0)
		return 0;

	return 1;
}

static void hash_plugin_check_hash(int index)
{
	unsigned char hmacsha1_key_[20];
	unsigned char aes_key_[32];
	int j;

	if (cur_salt->headerver == 1) {
#ifdef SIMD_COEF_32
		unsigned char *derived_key, Derived_key[SSE_GROUP_SZ_SHA1][32];
		int lens[SSE_GROUP_SZ_SHA1], i;
		unsigned char *pin[SSE_GROUP_SZ_SHA1];
		union {
			ARCH_WORD_32 *pout[SSE_GROUP_SZ_SHA1];
			unsigned char *poutc;
		} x;
		for (i = 0; i < SSE_GROUP_SZ_SHA1; ++i) {
			lens[i] = strlen(saved_key[index+i]);
			pin[i] = (unsigned char*)saved_key[index+i];
			x.pout[i] = (ARCH_WORD_32*)(Derived_key[i]);
		}
		pbkdf2_sha1_sse((const unsigned char **)pin, lens, cur_salt->salt, 20,
			cur_salt->iterations, &(x.poutc), 32, 0);
#else
		unsigned char derived_key[32];
		const char *password = saved_key[index];
		pbkdf2_sha1((const unsigned char*)password, strlen(password),
		       cur_salt->salt, 20, cur_salt->iterations, derived_key, 32, 0);
#endif
		j = 0;
#ifdef SIMD_COEF_32
		for(j = 0; j < SSE_GROUP_SZ_SHA1; ++j) {
		derived_key = Derived_key[j];
#endif
		if (apple_des3_ede_unwrap_key1(cur_salt->wrapped_aes_key, cur_salt->len_wrapped_aes_key, derived_key) &&
		    apple_des3_ede_unwrap_key1(cur_salt->wrapped_hmac_sha1_key, cur_salt->len_hmac_sha1_key, derived_key)) {
			cracked[index+j] = 1;
		}
#ifdef SIMD_COEF_32
		}
#endif
	} else {
		DES_key_schedule ks1, ks2, ks3;
		unsigned char TEMP1[sizeof(cur_salt->wrapped_hmac_sha1_key)];
		AES_KEY aes_decrypt_key;
		unsigned char outbuf[8192 + 1];
		unsigned char outbuf2[4096 + 1];
		unsigned char iv[20];
#ifdef DMG_DEBUG
		unsigned char *r;
#endif
		const char nulls[8] = { 0 };

#ifdef SIMD_COEF_32
		unsigned char *derived_key, Derived_key[SSE_GROUP_SZ_SHA1][32];
		int lens[SSE_GROUP_SZ_SHA1], i;
		unsigned char *pin[SSE_GROUP_SZ_SHA1];
		union {
			ARCH_WORD_32 *pout[SSE_GROUP_SZ_SHA1];
			unsigned char *poutc;
		} x;
		for (i = 0; i < SSE_GROUP_SZ_SHA1; ++i) {
			lens[i] = strlen(saved_key[index+i]);
			pin[i] = (unsigned char*)saved_key[index+i];
			x.pout[i] = (ARCH_WORD_32*)(Derived_key[i]);
		}
		pbkdf2_sha1_sse((const unsigned char **)pin, lens, cur_salt->salt, 20,
			cur_salt->iterations, &(x.poutc), 32, 0);
#else
		unsigned char derived_key[32];
		const char *password = saved_key[index];
		pbkdf2_sha1((const unsigned char*)password, strlen(password),
		       cur_salt->salt, 20, cur_salt->iterations, derived_key, 32, 0);
#endif
		j = 0;
#ifdef SIMD_COEF_32
		for(j = 0; j < SSE_GROUP_SZ_SHA1; ++j) {
		derived_key = Derived_key[j];
#endif

		DES_set_key((DES_cblock*)(derived_key +  0), &ks1);
		DES_set_key((DES_cblock*)(derived_key +  8), &ks2);
		DES_set_key((DES_cblock*)(derived_key + 16), &ks3);
		memcpy(iv, cur_salt->iv, 8);
		DES_ede3_cbc_encrypt(cur_salt->encrypted_keyblob, TEMP1,
		                     cur_salt->encrypted_keyblob_size, &ks1, &ks2, &ks3,
		                     (DES_cblock*)iv, DES_DECRYPT);

		memcpy(aes_key_, TEMP1, 32);
		memcpy(hmacsha1_key_, TEMP1, 20);
		hmac_sha1(hmacsha1_key_, 20, (unsigned char*)&cur_salt->cno, 4, iv, 20);
		if (cur_salt->encrypted_keyblob_size == 48)
			AES_set_decrypt_key(aes_key_, 128, &aes_decrypt_key);
		else
			AES_set_decrypt_key(aes_key_, 128 * 2, &aes_decrypt_key);
		AES_cbc_encrypt(cur_salt->chunk, outbuf, cur_salt->data_size, &aes_decrypt_key, iv, AES_DECRYPT);

		/* 8 consecutive nulls */
		if (memmem(outbuf, cur_salt->data_size, (void*)nulls, 8)) {
#ifdef DMG_DEBUG
			if (!bench_running)
				fprintf(stderr, "NULLS found!\n\n");
#endif
			cracked[index+j] = 1;
		}

/* These tests seem to be obsoleted by the 8xNULL test */
#ifdef DMG_DEBUG
		/* </plist> is a pretty generic signature for Apple */
		if (!cracked[index+j] && memmem(outbuf, cur_salt->data_size, (void*)"</plist>", 8)) {
			if (!bench_running)
				fprintf(stderr, "</plist> found!\n\n");
			cracked[index+j] = 1;
		}

		/* Journalled HFS+ */
		if (!cracked[index+j] && memmem(outbuf, cur_salt->data_size, (void*)"jrnlhfs+", 8)) {
			if (!bench_running)
				fprintf(stderr, "jrnlhfs+ found!\n\n");
			cracked[index+j] = 1;
		}

		/* Handle compressed DMG files, CMIYC 2012 and self-made
		   samples. Is this test obsoleted by the </plist> one? */
		if (!cracked[index+j] && (r = memmem(outbuf, cur_salt->data_size, (void*)"koly", 4))) {
			unsigned int *u32Version = (unsigned int *)(r + 4);

			if (HTONL(*u32Version) == 4) {
				if (!bench_running)
					fprintf(stderr, "koly found!\n\n");
				cracked[index+j] = 1;
			}
		}

		/* Handle VileFault sample images */
		if (!cracked[index+j] && memmem(outbuf, cur_salt->data_size, (void*)"EFI PART", 8)) {
			if (!bench_running)
				fprintf(stderr, "EFI PART found!\n\n");
			cracked[index+j] = 1;
		}

		/* Apple is a good indication but it's short enough to
		   produce false positives */
		if (!cracked[index+j] && memmem(outbuf, cur_salt->data_size, (void*)"Apple", 5)) {
			if (!bench_running)
				fprintf(stderr, "Apple found!\n\n");
			cracked[index+j] = 1;
		}

#endif /* DMG_DEBUG */

		/* Second buffer test. If present, *this* is the very first block of the DMG */
		if (!cracked[index+j] && cur_salt->scp == 1) {
			int cno = 0;

			hmac_sha1(hmacsha1_key_, 20, (unsigned char*)&cno, 4, iv, 20);
			if (cur_salt->encrypted_keyblob_size == 48)
				AES_set_decrypt_key(aes_key_, 128, &aes_decrypt_key);
			else
				AES_set_decrypt_key(aes_key_, 128 * 2, &aes_decrypt_key);
			AES_cbc_encrypt(cur_salt->zchunk, outbuf2, 4096, &aes_decrypt_key, iv, AES_DECRYPT);

			/* 8 consecutive nulls */
			if (memmem(outbuf2, 4096, (void*)nulls, 8)) {
#ifdef DMG_DEBUG
				if (!bench_running)
					fprintf(stderr, "NULLS found in alternate block!\n\n");
#endif
				cracked[index+j] = 1;
			}
#ifdef DMG_DEBUG
			/* This test seem to be obsoleted by the 8xNULL test */
			if (!cracked[index+j] && memmem(outbuf2, 4096, (void*)"Press any key to reboot", 23)) {
				if (!bench_running)
					fprintf(stderr, "MS-DOS UDRW signature found in alternate block!\n\n");
				cracked[index+j] = 1;
			}
#endif /* DMG_DEBUG */
		}

#ifdef DMG_DEBUG
		/* Write block as hex, strings or raw to a file. */
		if (cracked[index+j] && !bench_running) {
#if DMG_DEBUG == 4
			int fd;

			if ((fd = open("dmg.debug.main", O_RDWR | O_CREAT | O_TRUNC, 0660)) == -1)
				perror("open()");
			else {
#if FCNTL_LOCKS
				struct flock lock = { 0 };

				lock.l_type = F_WRLCK;
				while (fcntl(fd, F_SETLKW, &lock)) {
					if (errno != EINTR)
						pexit("fcntl(F_WRLCK)");
				}
#elif OS_FLOCK
				while (flock(fd, LOCK_EX)) {
					if (errno != EINTR)
						pexit("flock(LOCK_EX)");
				}
#endif
				if ((write(fd, outbuf, cur_salt->data_size) == -1))
					perror("write()");
				if (cur_salt->scp == 1)
					if ((write(fd, outbuf2, 4096) == -1))
						perror("write()");
				if (close(fd))
					perror("close");
			}
#endif
#if DMG_DEBUG == 3
			dump_stuff(outbuf, cur_salt->data_size);
			if (cur_salt->scp == 1) {
				fprintf(stderr, "2nd block:\n");
				dump_stuff(outbuf2, 4096);
			}
#endif
#if DMG_DEBUG == 2
			dump_text(outbuf, cur_salt->data_size);
			if (cur_salt->scp == 1) {
				fprintf(stderr, "2nd block:\n");
				dump_text(outbuf2, 4096);
			}
#endif
		}
#endif /* DMG_DEBUG */
#ifdef SIMD_COEF_32
		}
#endif
	}
	return;
}

static void set_salt(void *salt)
{
	cur_salt = (struct custom_salt *)salt;
#ifdef DMG_DEBUG
	//fprintf(stderr, "Blob size is %d bytes\n", cur_salt->data_size);
#endif
}

static void dmg_set_key(char *key, int index)
{
	int saved_len = strlen(key);
	if (saved_len > PLAINTEXT_LENGTH)
		saved_len = PLAINTEXT_LENGTH;
	memcpy(saved_key[index], key, saved_len);
	saved_key[index][saved_len] = 0;
}

static char *get_key(int index)
{
	return saved_key[index];
}

static int crypt_all(int *pcount, struct db_salt *salt)
{
	const int count = *pcount;
	int index;

	memset(cracked, 0, sizeof(cracked[0])*cracked_count);

#ifdef _OPENMP
#pragma omp parallel for
#endif
	for (index = 0; index < count; index += MAX_KEYS_PER_CRYPT)
	{
		hash_plugin_check_hash(index);
	}
	return count;
}

static int cmp_all(void *binary, int count)
{
	int index;
	for (index = 0; index < count; index++)
		if (cracked[index])
			return 1;
	return 0;
}

static int cmp_one(void *binary, int index)
{
	return cracked[index];
}

static int cmp_exact(char *source, int index)
{
	return 1;
}

static unsigned int iteration_count(void *salt)
{
	struct custom_salt *my_salt;

	my_salt = salt;
	return (unsigned int) my_salt->iterations;
}

struct fmt_main fmt_dmg = {
	{
		FORMAT_LABEL,
		FORMAT_NAME,
		ALGORITHM_NAME,
		BENCHMARK_COMMENT,
		BENCHMARK_LENGTH,
		0,
		PLAINTEXT_LENGTH,
		BINARY_SIZE,
		BINARY_ALIGN,
		SALT_SIZE,
		SALT_ALIGN,
		MIN_KEYS_PER_CRYPT,
		MAX_KEYS_PER_CRYPT,
#ifdef DMG_DEBUG
		FMT_NOT_EXACT |
#endif
		FMT_CASE | FMT_8_BIT | FMT_OMP,
		{
			"iteration count",
		},
		{ FORMAT_TAG },
		dmg_tests
	}, {
		init,
		done,
		fmt_default_reset,
		fmt_default_prepare,
		valid,
		fmt_default_split,
		fmt_default_binary,
		get_salt,
		{
			iteration_count,
		},
		fmt_default_source,
		{
			fmt_default_binary_hash /* Not usable with $SOURCE_HASH$ */
		},
		fmt_default_salt_hash,
		NULL,
		set_salt,
		dmg_set_key,
		get_key,
		fmt_default_clear_keys,
		crypt_all,
		{
			fmt_default_get_hash /* Not usable with $SOURCE_HASH$ */
		},
		cmp_all,
		cmp_one,
		cmp_exact
	}
};

#endif /* plugin stanza */
